Skip to content

✨ Allow to have multiple Query parameter models#12944

Open
uriyyo wants to merge 20 commits intofastapi:masterfrom
uriyyo:multiple-query-params-models
Open

✨ Allow to have multiple Query parameter models#12944
uriyyo wants to merge 20 commits intofastapi:masterfrom
uriyyo:multiple-query-params-models

Conversation

@uriyyo
Copy link
Copy Markdown
Contributor

@uriyyo uriyyo commented Nov 16, 2024

Currently, it's allowed to have only one model as a query/headers/etc model parameter, in this PR I propose to remove this restriction. This PR should be backward-compatible.

For instance, example below will not work:

from typing import Annotated

from pydantic import BaseModel

from fastapi import FastAPI, Query

app = FastAPI()


class FilterParams(BaseModel):
    name: str
    age: int


class PageParams(BaseModel):
    limit: int
    offset: int


@app.get("/")
async def route(
    filters: Annotated[FilterParams, Query()],
    page: Annotated[PageParams, Query()],
):
    return {}

And same here:

from typing import Annotated

from pydantic import BaseModel

from fastapi import FastAPI, Query

app = FastAPI()


class FilterParams(BaseModel):
    name: str
    age: int


@app.get("/")
async def route(
    filters: Annotated[FilterParams, Query()],
    limit: Annotated[int, Query()],
    offset: Annotated[int, Query()],
):
    return {}

WIth this PR both examples above will work as expected. Also, it will generate the correct OpenAPI schema:
image

Discussion - #12212

@wu-clan
Copy link
Copy Markdown

wu-clan commented Nov 17, 2024

This looks similar to #12481

@uriyyo
Copy link
Copy Markdown
Contributor Author

uriyyo commented Nov 17, 2024

I agree, It does solve the same issue. I didn't see it when I started working on this PR(

@svlandeg svlandeg added the feature New feature or request label Nov 25, 2024
@svlandeg svlandeg changed the title Allow to have multiple Query parameter models ✨ Allow to have multiple Query parameter models Nov 25, 2024
@jperuggia
Copy link
Copy Markdown

Hope this gets approved and released soon !

Comment on lines +216 to +222
fields_to_extract = []
for f in fields:
if lenient_issubclass(f.type_, BaseModel):
fields_to_extract.extend(get_cached_model_fields(f.type_))
else:
fields_to_extract.append(f)
return fields_to_extract
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this could be simplified a little bit:

fields_to_extract = [get_cached_model_fields(f.type_) for f in fields if lenient_issubclass(f.type_, BaseModel)]
fields.extend(fields_to_extract)
return fields

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it will work, because we will have both base model and all fields, we want to remove based model and keep only it fields.

Comment thread fastapi/dependencies/utils.py Outdated
@Mulugruntz
Copy link
Copy Markdown

This looks awesome! Really looking forward to it!
Do we know if/when it'll be approved and released?

@Vaserty
Copy link
Copy Markdown

Vaserty commented Mar 15, 2025

Do we know when this will be published? It would make things easier.

@uriyyo uriyyo requested a review from Ale-Cas August 5, 2025 09:31
@uriyyo
Copy link
Copy Markdown
Contributor Author

uriyyo commented Aug 5, 2025

Just merged with master and fixed tests, @Kludex any chance you can take a look on this PR? 🙏

@bassemkaroui
Copy link
Copy Markdown

@Ale-Cas can you please take a look at this ?

@bobbyo
Copy link
Copy Markdown

bobbyo commented Sep 15, 2025

is this merging soon? would be nice to have pagination and query on models in FastAPI, which is blocked on merging this PR ....

@github-actions github-actions Bot added the conflicts Automatically generated when a PR has a merge conflict label Oct 11, 2025
@github-actions

This comment was marked as resolved.

@bjmc
Copy link
Copy Markdown

bjmc commented Nov 20, 2025

Just chiming in that my team are also interested in this feature. 🙏

@bjmc
Copy link
Copy Markdown

bjmc commented Nov 21, 2025

I've just noticed that the same limitation seems to affect Form(), could this fix be extended to cover form POST as well?

Copilot AI review requested due to automatic review settings December 11, 2025 21:58
@github-actions github-actions Bot removed the conflicts Automatically generated when a PR has a merge conflict label Dec 11, 2025
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables FastAPI to support multiple Pydantic model parameters for Query, Header, and Cookie annotations. Previously, only a single model parameter was allowed per endpoint. The changes update the parameter flattening and validation logic to handle multiple models or a mix of model and scalar parameters.

Key changes:

  • Modified _get_flat_fields_from_params to iterate through all fields and extract model fields for each
  • Refactored request_params_to_args to process multiple BaseModel parameters by building a comprehensive parameter dictionary and validating each field appropriately
  • Added comprehensive test coverage for multiple models and mixed scenarios across Query, Header, and Cookie parameters

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
fastapi/dependencies/utils.py Updated parameter processing logic to handle multiple Pydantic models in _get_flat_fields_from_params and request_params_to_args functions
tests/test_multiple_params_models.py Added comprehensive tests validating multiple parameter models and mixed scenarios for Query, Header, and Cookie parameters, including OpenAPI schema verification

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread fastapi/dependencies/utils.py Outdated
Comment thread fastapi/dependencies/utils.py Outdated
@github-actions github-actions Bot added the conflicts Automatically generated when a PR has a merge conflict label Dec 12, 2025
@github-actions
Copy link
Copy Markdown
Contributor

This pull request has a merge conflict that needs to be resolved.

@github-actions github-actions Bot removed the conflicts Automatically generated when a PR has a merge conflict label Feb 8, 2026
@uriyyo
Copy link
Copy Markdown
Contributor Author

uriyyo commented Feb 8, 2026

Hi @tiangolo,

Any chance you can take a look at this PR? 🙏

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Feb 8, 2026

CodSpeed Performance Report

Merging this PR will not alter performance

Comparing uriyyo:multiple-query-params-models (ed24198) with master (376e108)1

Summary

✅ 20 untouched benchmarks

Footnotes

  1. No successful run was found on master (cd31576) during the generation of this report, so 376e108 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@wu-clan
Copy link
Copy Markdown

wu-clan commented Feb 8, 2026

The maintenance team seems to be moving forward with #12481, but still have to wait for a response from tiangolo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.