fastapi 查询参数支持 Pydantic Model:参数校验与配置技巧
本文介绍了 FastAPI 中通过 Pydantic model 声明查询参数的使用方法,提供了更加灵活和强大的参数校验方式。通过将查询参数定义在 Pydantic model 中,开发者可以对参数设置默认值、约束条件,并统一管理查询参数校验逻辑。此外,还演示了如何禁用额外参数,以确保客户端请求仅包含允许的字段。文章中的完整代码示例展示了如何轻松复用模型配置,提高 API 的规范性与可靠性。
文章目录
- fastapi 查询参数支持 Pydantic Model:参数校验与配置技巧
- 一 声明查询参数
- 二 禁止额外参数
- 三 完整代码示例
- 四 源码地址
预备课:
深入解析 FastAPI 查询参数:配置、类型转换与灵活组合
FastAPI 查询参数与字符串校验详解:类型、校验规则与元数据设置
示例中使用的 Python 版本为 Python 3.10.15
,FastAPI 版本为 0.115.4
。
自 FastAPI 版本 0.115.0
起,支持通过 Pydantic model 声明一组查询参数。这样不仅可以在多个位置复用该 model ,还能一次性为所有参数提供验证和元数据。本文中,Pydantic model 将译为 Pydantic 模型,以下统一称为 Pydantic 模型。
一 声明查询参数
使用 Pydantic 模型定义所需的查询参数,并使用 Query 来声明这些参数。
from typing import Literal, Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
app = FastAPI()
class FilterParams(BaseModel):
limit: int = Field(100, gt=0, le=100)
offset: int = Field(0, ge=0)
order_by: Literal["created_at", "updated_at"] = "created_at"
tags: list[str] = []
@app.get("/items/")
async def read_items(filter_query: FilterParams = Query()):
return filter_query
可运行代码文件 chapter07.py 来启动应用:
$ uvicorn chapter07:app --reload
在 SwaggerUI 中可以查看在线文档:http://127.0.0.1:8000/docs
。也可以使用 Annotated 声明
@app.get("/items03/")
async def read_items(filter_query: Annotated[FilterParams, Query()]):
return filter_query
FastAPI 会从请求的查询参数中提取各字段数据,并返回定义的 Pydantic 模型。
二 禁止额外参数
使用 Pydantic 模型配置来禁止任何额外参数字段。
class FilterParams04(BaseModel):
model_config = {"extra": "forbid"}
limit: int = Field(100, gt=0, le=100)
offset: int = Field(0, ge=0)
order_by: Literal["created_at", "updated_at"] = "created_at"
tags: list[str] = []
@app.get("/items04/")
async def read_items(filter_query: FilterParams04 = Query()):
return filter_query
客户端在查询参数中发送多余数据时会收到错误响应。例如,客户端尝试发送一个值为 plumbus 的 tool
查询参数。
http://127.0.0.1:8000/items04/?limit=100&offset=0&order_by=created_at&tool=plumbus
收到的错误响应:
{
"detail": [
{
"type": "extra_forbidden",
"loc": [
"query",
"tool"
],
"msg": "Extra inputs are not permitted",
"input": "plumbus"
}
]
}
三 完整代码示例
from typing import Literal, Annotated
from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
app = FastAPI()
class FilterParams(BaseModel):
limit: int = Field(100, gt=0, le=100)
offset: int = Field(0, ge=0)
order_by: Literal["created_at", "updated_at"] = "created_at"
tags: list[str] = []
@app.get("/items/")
async def read_items(filter_query: FilterParams = Query()):
return filter_query
@app.get("/items03/")
async def read_items(filter_query: Annotated[FilterParams, Query()]):
return filter_query
class FilterParams02(BaseModel):
model_config = {"extra": "forbid"}
limit: int = Field(100, gt=0, le=100)
offset: int = Field(0, ge=0)
order_by: Literal["created_at", "updated_at"] = "created_at"
tags: list[str] = []
@app.get("/items02/")
async def read_items(filter_query: FilterParams02 = Query()):
return filter_query
class FilterParams04(BaseModel):
model_config = {"extra": "forbid"}
limit: int = Field(100, gt=0, le=100)
offset: int = Field(0, ge=0)
order_by: Literal["created_at", "updated_at"] = "created_at"
tags: list[str] = []
@app.get("/items04/")
async def read_items(filter_query: FilterParams04 = Query()):
return filter_query
四 源码地址
详情见:GitHub FastApiProj
引用: FastAPI 文档