696 字
3 分钟
参数校验
查询参数和字符串校验
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")async def read_items(q: str | None = None): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) return results
查询参数 q 的类型为 str,默认为 None,因此他是可选的
额外的检验
即使 Q 是可选的,但只要提供了该参数,该参数的长度要<50
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")async def read_items(q: Union[str, None] = Query(default=None, max_length=50)): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) return results
这里我们使用了 Query 来替代 None,并且设置他的最大长度为 50
当使用 Query 当你使用 Query
显式地定义查询参数时,你还可以声明它去接收一组值,或换句话来说,接收多个值。
例如,要声明一个可在 URL 中出现多次的查询参数 q
,你可以这样写:
from typing import List, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")async def read_items(q: Union[List[str], None] = Query(default=None)): query_items = {"q": q} return query_items
我们可以在 query 中添加更多的元数据用于描述我们的代码
@app.get("/items/")async def read_items( q: Union[str, None] = Query( default=None, title="Query string", description="Query string for the items to search in the database that have a good match", min_length=3, deprecated=True,#表示将要弃用 ),): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if q: results.update({"q": q}) return results
路径参数和数值校验
与 query 相似,我们也可是使用 Path 为路径参数声明校验和元数据
from typing import Annotated
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")async def read_items( item_id: Annotated[int, Path(title="The ID of the item to get")], q: Annotated[str | None, Query(alias="item-query")] = None,): results = {"item_id": item_id} if q: results.update({"q": q}) return results
这里的 Annotated 就是加点辅助信息
路径参数是必须得,即使被申明为=None!,所以路径参数应该放在 query 的前面 (如果你将带有「默认值」的参数放在没有「默认值」的参数之前,Python 将会报错。)
数值校验
@app.get("/items/{item_id}")async def read_items( item_id: Annotated[int, Path(title="The ID of the item to get", ge=1,le=1000)], q: str): results = {"item_id": item_id} if q: results.update({"q": q}) return results
查询参数
可以使用 pydantic 模型来声明它们
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: Annotated[FilterParams, Query()]): return filter_query
与在路径操作函数中使用 Query、Path 、Body 声明校验与元数据的方式一样,可以使用 Pydantic 的 Field 在 Pydantic 模型内部声明校验和元数据。
请求体
from typing import Annotated
from fastapi import Body, FastAPIfrom pydantic import BaseModel
app = FastAPI()
class Item(BaseModel): name: str description: str | None = None price: float tax: float | None = None
class User(BaseModel): username: str full_name: str | None = None
@app.put("/items/{item_id}")async def update_item( item_id: int, item: Item, user: User, importance: Annotated[int, Body(gt=0)]): results = {"item_id": item_id, "item": item, "user": user, "importance": importance} return results
这里的 importance 是一个单一值,请求体应该如下:
{ "item": { "name": "Foo", "description": "The pretender", "price": 42.0, "tax": 3.2 }, "user": { "username": "dave", "full_name": "Dave Grohl" }, "importance": 5}