Browse Source

🐛 Fix parsing extra `Form` parameter list (#14303)

Co-authored-by: Sebastián Ramírez <[email protected]>
pull/14432/head
Motov Yurii 6 months ago
committed by GitHub
parent
commit
6cf40df24d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 8
      fastapi/dependencies/utils.py
  2. 47
      tests/test_forms_single_model.py

8
fastapi/dependencies/utils.py

@ -903,9 +903,13 @@ async def _extract_form_body(
if value is not None:
values[field.alias] = value
field_aliases = {field.alias for field in body_fields}
for key, value in received_body.items():
for key in received_body.keys():
if key not in field_aliases:
values[key] = value
param_values = received_body.getlist(key)
if len(param_values) == 1:
values[key] = param_values[0]
else:
values[key] = param_values
return values

47
tests/test_forms_single_model.py

@ -2,6 +2,7 @@ from typing import List, Optional
from dirty_equals import IsDict
from fastapi import FastAPI, Form
from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
from typing_extensions import Annotated
@ -17,11 +18,27 @@ class FormModel(BaseModel):
alias_with: str = Field(alias="with", default="nothing")
class FormModelExtraAllow(BaseModel):
param: str
if PYDANTIC_V2:
model_config = {"extra": "allow"}
else:
class Config:
extra = "allow"
@app.post("/form/")
def post_form(user: Annotated[FormModel, Form()]):
return user
@app.post("/form-extra-allow/")
def post_form_extra_allow(params: Annotated[FormModelExtraAllow, Form()]):
return params
client = TestClient(app)
@ -131,3 +148,33 @@ def test_no_data():
]
}
)
def test_extra_param_single():
response = client.post(
"/form-extra-allow/",
data={
"param": "123",
"extra_param": "456",
},
)
assert response.status_code == 200, response.text
assert response.json() == {
"param": "123",
"extra_param": "456",
}
def test_extra_param_list():
response = client.post(
"/form-extra-allow/",
data={
"param": "123",
"extra_params": ["456", "789"],
},
)
assert response.status_code == 200, response.text
assert response.json() == {
"param": "123",
"extra_params": ["456", "789"],
}

Loading…
Cancel
Save