FastAPI入门:查询参数模型、多个请求体参数
查询参数模型
如果你有一组具有相关性的查询参数,你可以创建一个 Pydantic 模型来声明它们。
这将允许你在多个地方去复用模型,并且一次性为所有参数声明验证和元数据
pydantic声明参数
在一个 Pydantic 模型中声明你需要的查询参数,然后将参数声明为 Query
Literal 用于创建一个类型,该类型只能是指定的确切值。相当于枚举类型?
Field是 Pydantic 中用于为模型字段添加验证规则、默认值和元数据的函数。和Path和Query的区别是它只能用于pydantic模型字段
from fastapi import FastAPI, Query , Path# 导入Path和Query类
from typing import Annotated, Literal
from pydantic import BaseModel, Fieldclass 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 = FastAPI()@app.get("/items/")
# 将 Query 用作查询参数的默认值,并将它的 max_length 参数设置为 50
async def read_items(filter_query: Annotated[FilterParams, Query()]):return filter_query
FastAPI 将会从请求的查询参数中提取出每个字段的数据,并将其提供给你定义的 Pydantic 模型。
禁止额外的查询参数
在一些特殊的使用场景中(可能不是很常见),你可能希望限制你要接收的查询参数。
你可以使用 Pydantic 的模型配置来禁止任何额外的字段
class FilterParams(BaseModel):model_config = {"extra": "forbid"}
此时如果添加其他参数,会报错
多个请求体参数
声明多个pydantic类型作为不同请求体的数据模型
class Item(BaseModel):name: strdescription: str | None = Noneprice: floattax: float | None = Noneclass User(BaseModel):username: strfull_name: str | None = None
接受多个请求体
app = FastAPI()@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, user: User):result = {"item_id": item_id,"item": item,"user": user}return result
此时将会接受形如下面JSON的请求体
{"item": {"name": "string","description": "string","price": 0,"tax": 0},"user": {"username": "string","full_name": "string"}
}
请求体中的单一值
类似于Path和Query,可以使用Body声明请求体
async def update_item(item_id: int, item: Item, user: User, importance: Annotated[int, Body()]):result = {"item_id": item_id,"item": item,"user": user,"importance": importance}return result
此时代码期待如下格式的请求体:
{"item": {"name": "string","description": "string","price": 0,"tax": 0},"user": {"username": "string","full_name": "string"},"importance": 0
}
嵌入单个请求体参数
你希望它期望一个拥有 item 键并在值中包含模型内容的 JSON,就像在声明额外的请求体参数时所做的那样,则可以使用一个特殊的 Body 参数 embed
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):result = {"item_id": item_id,"item": item}return result
在这种情况下,FastAPI 将期望像这样的请求体:
{"item": {"name": "Foo","description": "The pretender","price": 42.0,"tax": 3.2}
}
而不是
{"name": "Foo","description": "The pretender","price": 42.0,"tax": 3.2
}