Pydantic 是 FastAPI 的核心组件,用于数据验证和序列化。通过 Pydantic,我们可以轻松定义强类型数据模型,并自动完成数据校验。本文将介绍如何在 FastAPI 中结合 Pydantic 使用,帮助你更高效地构建 API。
什么是 Pydantic?
Pydantic 是一个用于数据验证和数据解析的 Python 库。它基于 Python 的类型注解(type hints)定义数据结构,并在运行时执行验证。Pydantic 能够简化输入验证和数据转换的逻辑,确保数据的正确性和一致性。
安装 Pydantic
FastAPI 默认集成了 Pydantic,因此在安装 FastAPI 后无需单独安装 Pydantic。如果你需要单独安装 Pydantic,可以使用以下命令:
pip install pydantic
使用 Pydantic 定义数据模型
Pydantic 允许我们通过继承 BaseModel 类来定义数据模型。在 FastAPI 中,这些模型用于验证请求体数据,并自动转换为对应的 Python 类型。
示例代码
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# 定义 Pydantic 数据模型
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.post("/items/")
async def create_item(item: Item):
return {"item": item}
示例解析
-
定义数据模型:
- 使用
BaseModel定义Item模型,其中包含name,description,price, 和tax字段。 description和tax字段是可选的(使用None作为默认值)。
- 使用
-
自动验证:
FastAPI 会根据Item模型的定义自动校验请求体中的数据是否符合要求,确保数据类型和约束条件的正确性。 -
POST 请求:
路由/items/接收 JSON 格式的请求数据,并将其解析为Item实例。
测试模型
运行应用后,使用工具(如 Postman 或 cURL)发送 POST 请求:
curl -X POST "http://127.0.0.1:8000/items/" -H "Content-Type: application/json" -d '{"name": "Laptop", "price": 999.99}'
成功响应
{
"item": {
"name": "Laptop",
"description": null,
"price": 999.99,
"tax": null
}
}
错误示例
如果请求数据格式不正确,例如缺少必填字段 name,FastAPI 将返回 422 状态码,并提示错误信息:
{
"detail": [
{
"loc": ["body", "name"],
"msg": "field required",
"type": "value_error.missing"
}
]
}
Pydantic 高级特性
1. 默认值与校验
Pydantic 支持通过字段定义默认值,并提供丰富的校验功能。你可以使用 Field 来设置字段的约束和元数据。
from pydantic import BaseModel, Field
class User(BaseModel):
username: str = Field(..., title="Username", min_length=3, max_length=20)
age: int = Field(..., ge=18, le=100, description="Age must be between 18 and 100")
Field用于为字段设置额外的校验条件。username字段的长度限制为 3 到 20。age字段的值必须在 18 到 100 之间。
2. 嵌套模型
Pydantic 支持嵌套模型,可以通过定义子模型来表示复杂的数据结构。
from pydantic import BaseModel
class Address(BaseModel):
city: str
zip_code: str
class User(BaseModel):
name: str
address: Address
@app.post("/users/")
async def create_user(user: User):
return {"user": user}
请求示例:
{
"name": "Alice",
"address": {
"city": "New York",
"zip_code": "10001"
}
}
3. 数据转换与校正
Pydantic 自动尝试将输入数据转换为指定类型,这样我们可以避免手动类型转换。
from pydantic import BaseModel
class Item(BaseModel):
price: float
item = Item(price="19.99")
print(item.price) # 输出: 19.99 (字符串自动转换为浮点数)
4. 使用 Pydantic @property 格式化日期
在某些情况下,我们希望将日期字段格式化为特定的字符串格式。可以通过 Pydantic 的 @property 装饰器来实现。
from fastapi import FastAPI
from pydantic import BaseModel
from datetime import datetime
app = FastAPI()
class Event(BaseModel):
name: str
start_time: datetime
@property
def formatted_start_time(self):
return self.start_time.strftime("%Y-%m-%d %H:%M:%S")
@app.post("/events/")
async def create_event(event: Event):
return {"event": event, "formatted_start_time": event.formatted_start_time}
示例输出
{
"event": {
"name": "Python Workshop",
"start_time": "2024-12-20T15:00:00"
},
"formatted_start_time": "2024-12-20 15:00:00"
}
解析:通过 @property 装饰器将 start_time 格式化为指定的字符串格式。原始的 start_time 仍然是 datetime 类型,格式化后的输出仅在响应中有效。
5. 使用 Pydantic json_encoders 格式化日期
另一种方法是使用 Pydantic 模型的 Config 类中的 json_encoders 配置项,这样可以全局设置日期字段的格式化规则。
from fastapi import FastAPI
from pydantic import BaseModel
from datetime import datetime
app = FastAPI()
class Event(BaseModel):
name: str
start_time: datetime
class Config:
# 设置 json_encoders 格式化规则
json_encoders = {
datetime: lambda v: v.strftime("%Y-%m-%d %H:%M:%S")
}
@app.post("/events/")
async def create_event(event: Event):
return {"event": event}
示例输出
{
"event": {
"name": "Python Workshop",
"start_time": "2024-12-20 15:00:00"
}
}
解析:在 Config 类中,通过 json_encoders 字典设置了全局的 datetime 格式化规则。这样,所有的 datetime 字段都会自动使用该格式进行格式化。
Pydantic 配合依赖注入
FastAPI 支持将 Pydantic 模型与依赖注入结合使用,使得查询参数、路径参数等可以自动解析为 Pydantic 模型。
from fastapi import Depends
class QueryParams(BaseModel):
q: str
limit: int = 10
@app.get("/search/")
async def search(params: QueryParams = Depends()):
return {"query": params.q, "limit": params.limit}
在上述示例中,Depends 会自动将查询参数解析为 QueryParams 对象。
总结
通过本文,我们学习了如何在 FastAPI 中使用 Pydantic,包括:
- 定义基础数据模型。
- 验证请求数据并提供详细的错误信息。
- 使用 Pydantic 的高级功能(嵌套模型、字段约束、自动类型转换等)。
- 格式化日期输出,并将其与 FastAPI API 响应集成。
为什么选择 Pydantic?
- 强大的数据校验:简化输入验证逻辑,确保数据符合预期。
- 高效解析与转换:自动进行类型转换和校正。
- 现代化的类型支持:基于 Python 的类型注解,代码可读性更高,易于维护。
2054

被折叠的 条评论
为什么被折叠?



