mirror of https://github.com/tiangolo/fastapi.git
🐛 Fix parsing extra non-body parameter list (#14356)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
parent
2330e2de75
commit
de5bec637c
|
|
@ -791,9 +791,16 @@ def request_params_to_args(
|
|||
processed_keys.add(alias or field.alias)
|
||||
processed_keys.add(field.name)
|
||||
|
||||
for key, value in received_params.items():
|
||||
for key in received_params.keys():
|
||||
if key not in processed_keys:
|
||||
if hasattr(received_params, "getlist"):
|
||||
value = received_params.getlist(key)
|
||||
if isinstance(value, list) and (len(value) == 1):
|
||||
params_to_process[key] = value[0]
|
||||
else:
|
||||
params_to_process[key] = value
|
||||
else:
|
||||
params_to_process[key] = received_params.get(key)
|
||||
|
||||
if single_not_embedded_field:
|
||||
field_info = first_field.field_info
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
from fastapi import Cookie, FastAPI, Header, Query
|
||||
from fastapi._compat import PYDANTIC_V2
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Model(BaseModel):
|
||||
param: str
|
||||
|
||||
if PYDANTIC_V2:
|
||||
model_config = {"extra": "allow"}
|
||||
else:
|
||||
|
||||
class Config:
|
||||
extra = "allow"
|
||||
|
||||
|
||||
@app.get("/query")
|
||||
async def query_model_with_extra(data: Model = Query()):
|
||||
return data
|
||||
|
||||
|
||||
@app.get("/header")
|
||||
async def header_model_with_extra(data: Model = Header()):
|
||||
return data
|
||||
|
||||
|
||||
@app.get("/cookie")
|
||||
async def cookies_model_with_extra(data: Model = Cookie()):
|
||||
return data
|
||||
|
||||
|
||||
def test_query_pass_extra_list():
|
||||
client = TestClient(app)
|
||||
resp = client.get(
|
||||
"/query",
|
||||
params={
|
||||
"param": "123",
|
||||
"param2": ["456", "789"], # Pass a list of values as extra parameter
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json() == {
|
||||
"param": "123",
|
||||
"param2": ["456", "789"],
|
||||
}
|
||||
|
||||
|
||||
def test_query_pass_extra_single():
|
||||
client = TestClient(app)
|
||||
resp = client.get(
|
||||
"/query",
|
||||
params={
|
||||
"param": "123",
|
||||
"param2": "456",
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json() == {
|
||||
"param": "123",
|
||||
"param2": "456",
|
||||
}
|
||||
|
||||
|
||||
def test_header_pass_extra_list():
|
||||
client = TestClient(app)
|
||||
|
||||
resp = client.get(
|
||||
"/header",
|
||||
headers=[
|
||||
("param", "123"),
|
||||
("param2", "456"), # Pass a list of values as extra parameter
|
||||
("param2", "789"),
|
||||
],
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
resp_json = resp.json()
|
||||
assert "param2" in resp_json
|
||||
assert resp_json["param2"] == ["456", "789"]
|
||||
|
||||
|
||||
def test_header_pass_extra_single():
|
||||
client = TestClient(app)
|
||||
|
||||
resp = client.get(
|
||||
"/header",
|
||||
headers=[
|
||||
("param", "123"),
|
||||
("param2", "456"),
|
||||
],
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
resp_json = resp.json()
|
||||
assert "param2" in resp_json
|
||||
assert resp_json["param2"] == "456"
|
||||
|
||||
|
||||
def test_cookie_pass_extra_list():
|
||||
client = TestClient(app)
|
||||
client.cookies = [
|
||||
("param", "123"),
|
||||
("param2", "456"), # Pass a list of values as extra parameter
|
||||
("param2", "789"),
|
||||
]
|
||||
resp = client.get("/cookie")
|
||||
assert resp.status_code == 200
|
||||
resp_json = resp.json()
|
||||
assert "param2" in resp_json
|
||||
assert resp_json["param2"] == "789" # Cookies only keep the last value
|
||||
|
|
@ -77,7 +77,7 @@ def test_header_param_model_no_underscore(client: TestClient):
|
|||
"user-agent": "testclient",
|
||||
"save-data": "true",
|
||||
"if-modified-since": "yesterday",
|
||||
"x-tag": "two",
|
||||
"x-tag": ["one", "two"],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue