FastAPI 響應模型:Pydantic 的數(shù)據(jù)驗證與轉(zhuǎn)換,一篇吃透!
是否遇到過這些問題?
- 數(shù)據(jù)庫返回字段太多,前端只要幾個?
- 接口文檔不一致,測試老是報錯?
- ORM 對象直接返回,總是類型錯誤?
快用 FastAPI 的響應模型(response_model)+ Pydantic,自動校驗、轉(zhuǎn)換、過濾、文檔全搞定!
1. 什么是響應模型?
響應模型用于定義接口的返回結(jié)構(gòu)。FastAPI 會根據(jù)響應模型:
- 自動校驗字段類型
- 自動過濾多余字段
- 自動轉(zhuǎn)換格式
- 自動生成文檔(OpenAPI)
2. 快速上手:定義響應結(jié)構(gòu)
from pydantic import BaseModel
class UserOut(BaseModel):
id: int
name: str
email: str
在接口中使用:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}", response_model=UserOut)
def get_user(user_id: int):
return {
"id": user_id,
"name": "Alice",
"email": "alice@example.com",
"is_admin": True # 會自動被過濾掉
}
最終返回只包含指定字段:
{
"id": 1,
"name": "Alice",
"email": "alice@example.com"
}
3. 支持嵌套模型和列表模型
class Address(BaseModel):
city: str
country: str
class UserOut(BaseModel):
id: int
name: str
address: Address
列表結(jié)構(gòu)也支持:
@app.get("/users/", response_model=list[UserOut])
def get_users():
return [...]
4. ORM 模式(必須開啟):與數(shù)據(jù)庫模型打通
如果你使用 SQLAlchemy、Tortoise ORM 等,接口函數(shù)中返回的是 ORM 實例而不是字典,就必須開啟 “ORM 模式”。
為什么要開啟?
因為 ORM 對象不是標準字典,Pydantic 默認不能識別對象的屬性,需要開啟專用模式:
(1) Pydantic v1 的寫法
class UserOut(BaseModel):
id: int
name: str
class Config:
orm_mode = True
FastAPI 會自動調(diào)用 obj.__dict__ 或?qū)傩苑椒?,提取字段?/p>
(2) Pydantic v2 的寫法(推薦)
class UserOut(BaseModel):
id: int
name: str
model_config = {
"from_attributes": True # 替代 orm_mode
}
from_attributes=True 更加清晰地表明“這個模型的字段可以從屬性中提取”。
(3) 搭配 SQLAlchemy 使用示例
from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)
# 響應模型
class UserOut(BaseModel):
id: int
name: str
model_config = {
"from_attributes": True
}
@app.get("/users/{id}", response_model=UserOut)
def get_user(id: int, db: Session = Depends(get_db)):
return db.query(User).get(id)
(4) 搭配 Tortoise ORM 使用示例
from tortoise.models import Model
from tortoise import fields
class User(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=50)
class UserOut(BaseModel):
id: int
name: str
model_config = {
"from_attributes": True
}
@app.get("/users/{id}", response_model=UserOut)
async def get_user(id: int):
user = await User.get(id=id)
return user
5. 響應字段別名與描述(自動生成文檔)
from pydantic import Field
class UserOut(BaseModel):
id: int
name: str = Field(..., alias="username", description="用戶名")
返回結(jié)構(gòu)變?yōu)椋?/p>
{
"id": 1,
"username": "Alice"
}
在 Swagger 文檔中也能自動顯示字段描述!
6. Pydantic v1 vs v2 對比
功能點 | v1 | v2(推薦) |
底層實現(xiàn) | Python 實現(xiàn) | Rust 實現(xiàn)(pydantic-core) |
性能 | 一般 | ?? 提升 5~50 倍 |
默認值聲明 | 可用 = | 推薦使用 Field() 顯式寫法 |
ORM 支持 | Config.orm_mode = True | model_config = {"from_attributes": True} |
JSON 解析 | Python 實現(xiàn) | 快速原生 JSON 序列化 |
聯(lián)合類型支持 | 較弱 | 強化了對 Union, Annotated 的支持 |
7. 總結(jié)
response_model 是 FastAPI 最強大功能之一,搭配 Pydantic 使用,自動:
- 校驗字段
- 過濾無用字段
- 自動格式轉(zhuǎn)換
- 自動生成 Swagger 文檔
- 無縫對接 ORM 模型對象
ORM 模式配置(orm_mode 或 from_attributes)一定不能忘,否則可能會返回空數(shù)據(jù)、字段丟失等問題。