From d1ac537285817664b1260597e10d372d7a329152 Mon Sep 17 00:00:00 2001 From: Nico Tonnhofer Date: Thu, 25 Sep 2025 12:18:54 +0200 Subject: [PATCH] Fix handle alias for query in pydantic model --- fastapi/dependencies/utils.py | 2 +- tests/test_query_single_model.py | 83 ++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 tests/test_query_single_model.py diff --git a/fastapi/dependencies/utils.py b/fastapi/dependencies/utils.py index e49380cb3..45962fcba 100644 --- a/fastapi/dependencies/utils.py +++ b/fastapi/dependencies/utils.py @@ -788,7 +788,7 @@ def request_params_to_args( ) value = _get_multidict_value(field, received_params, alias=alias) if value is not None: - params_to_process[field.name] = value + params_to_process[field.alias] = value processed_keys.add(alias or field.alias) processed_keys.add(field.name) diff --git a/tests/test_query_single_model.py b/tests/test_query_single_model.py new file mode 100644 index 000000000..f4379c4ec --- /dev/null +++ b/tests/test_query_single_model.py @@ -0,0 +1,83 @@ +from typing import List, Optional + +from dirty_equals import IsDict +from fastapi import FastAPI, Query +from fastapi.testclient import TestClient +from pydantic import BaseModel, Field +from typing_extensions import Annotated + +app = FastAPI() + + +class QueryModel(BaseModel): + item: List[int] = [] + with_alias: Optional[str] = Field(alias="withAlias", default=None) + without_alias: str = "default" + + +@app.get("/query") +def get_query(query: Annotated[QueryModel, Query()]): + return query + + +client = TestClient(app) + + +def test_query(): + response = client.get( + "/query", + params={ + "item": [1, 2], + "withAlias": "abc123", + "without_alias": "custom", + }, + ) + assert response.status_code == 200, response.text + assert response.json() == { + "item": [1, 2], + "withAlias": "abc123", + "without_alias": "custom", + } + + +def test_defaults(): + response = client.get("/query", params={"item": [1, 2]}) + assert response.status_code == 200, response.text + assert response.json() == { + "item": [1, 2], + "withAlias": None, + "without_alias": "default", + } + + +def test_invalid_data(): + response = client.get( + "/query", + params={ + "item": ["invalid"], + }, + ) + assert response.status_code == 422, response.text + assert response.json() == IsDict( + { + "detail": [ + { + "type": "int_parsing", + "loc": ["query", "item", 0], + "msg": "Input should be a valid integer, unable to parse string as an integer", + "input": "invalid", + } + ] + } + ) | IsDict( + # TODO: remove when deprecating Pydantic v1 + { + "detail": [ + { + "loc": ["query", "item", 0], + "msg": "Input should be a valid integer, unable to parse string as an integer", + "type": "type_error.int_parsing", + } + ] + } + )