首页  >  文章  >  后端开发  >  FastAPI:如何使用 Pydantic 声明查询参数

FastAPI:如何使用 Pydantic 声明查询参数

Linda Hamilton
Linda Hamilton原创
2024-10-10 06:11:30852浏览

它大约三周前发布,是 FastAPI 最受期待的功能之一。至少当我们谈论 Pydantic Models FastAPI 时。

是的,我说的是使用 Pydantic 模型来映射查询参数的能力。

所以在这篇文章中,我将尽力向您展示一切?可以和?对这个话题无能为力吗?:

?映射查询参数

要开始使用 Pydantic 映射查询参数,您需要做的第一件事是确保您使用的是 FastAPI 版本 0.115.0。

此后,您可以随时访问 FastAPI 文档来检查已有的内容。 Sebastián 和团队成员在保持文档更新和信息丰富方面做得非常非常出色 ✨。

?一点点历史

让我们从一些示例开始,了解如何在 FastAPI 中映射查询参数。 ?

最简单的方法是:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def search(
    limit: int | None = 10,
    skip: int | None = 1,
    filter: str | None = None
):
    return {
        "limit": limit,
        "skip": skip,
        "filter": filter
    }

现在您只需拨打:

GET http://localhost:8000/?limit=42&skip=12&filter=banana

但是如果我们确定此查询参数将在其他路由中使用,我们将使用以下内容将其隔离:

from typing import Any
from fastapi import Depends, FastAPI, Query

app = FastAPI()

async def pagination_query_string(
    limit: int | None = Query(10, ge=5, le=100),
    skip: int | None = Query(1, ge=1),
    filter: str | None = Query(None)
) -> dict[str, Any]:
    return {
        "limit": limit,
        "skip": skip,
        "filter": filter
    }

@app.get("/")
async def search(q: dict[str, Any] = Depends(pagination_query_string)):
    return q

或者因为我们使用 Pydantic 来映射我们的模型,只需一点重构,我们就会得到:

from fastapi import Depends, FastAPI, Query
from pydantic import BaseModel

app = FastAPI()

class PaginationQueryString(BaseModel):
    limit: int | None = 10
    skip: int | None = 1
    filter: str | None = None

async def pagination_query_string(
    limit: int | None = Query(10, ge=5, le=100),
    skip: int | None = Query(1, ge=1),
    filter: str | None = Query(None)
) -> PaginationQueryString:
    return PaginationQueryString(
        limit=limit,
        skip=skip,
        filter=filter
    )

@app.get("/")
async def search(q: PaginationQueryString = Depends(pagination_query_string)):
    return q

⌨️ 使用 Pydantic 映射查询字符串

FastAPI: How to use Pydantic to declare Query Parameters

现在,如果我们想要获取查询字符串,我们不需要创建一个函数,然后将其添加为依赖项。我们可以简单地告诉 FastAPI 我们想要一个 PaginationQueryString 类型的对象,并且它是一个查询字符串:

from typing import Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel

app = FastAPI()

class PaginationQueryString(BaseModel):
    limit: int | None = 10
    skip: int | None = 1
    filter: str | None = None

@app.get("/")
async def search(q: Annotated[PaginationQueryString, Query()]):
    return q

简单吧? ?

⚠️有什么限制?

至少在 0.115.0 版本中,它不能很好地处理嵌套模型。

让我们尝试一下:

from typing import Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel

app = FastAPI()

class Filter(BaseModel):
    name: str | None = None
    age: int | None = None
    nickname: str | None = None

class PaginationQueryString(BaseModel):
    limit: int | None = 10
    skip: int | None = 1
    filter: Filter | None = None

@app.get("/")
async def search(q: Annotated[PaginationQueryString, Query()]):
    return q

如果我们像以前那样称呼它:

GET http://localhost:8000/?limit=42&skip=12&filter=chocolate

我们会收到一个错误,告诉我们过滤器是一个对象:

{
    "detail": [
        {
            "type": "model_attributes_type",
            "loc": [
                "query",
                "filter"
            ],
            "msg": "Input should be a valid dictionary or object to extract fields from",
            "input": "chocolate"
        }
    ]
}

至少现在来说,是绝对正确的!我们将过滤器更改为 Pydantic 模型,而不是字符串。但如果我们尝试将其转换为字典:

http://localhost:8000/?limit=42&skip=12&filter={%22name%22:%20%22Rafael%22,%20%22age%22:%2038,%20%22nickname%22:%20%22ceb10n%22}

FastAPI 会告诉我们过滤器需要是一个有效的字典?:

{
    "detail": [
        {
            "type": "model_attributes_type",
            "loc": [
                "query",
                "filter"
            ],
            "msg": "Input should be a valid dictionary or object to extract fields from",
            "input": "{\"name\": \"Rafael\", \"age\": 38, \"nickname\": \"ceb10n\"}"
        }
    ]
}

发生这种情况是因为 FastAPI 将依赖 Starlette 的 QueryParams,它将向 FastAPI 提供一个字符串,而不是一个字典。至少在 0.115.0 版本中,这会给你一个错误。

⁉️ 那么,我什么时候应该在查询参数中使用 Pydantic 模型?

很简单:

✅ 您有简单的查询字符串,不需要任何复杂的花哨的嵌套对象?使用它! ?

❌ 您创建了一个复杂的嵌套查询字符串?还没有使用它吗? (也许您应该尝试重新考虑您的查询字符串。?越简单越好?)

以上是FastAPI:如何使用 Pydantic 声明查询参数的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn