如何用泛型Pydantic模型CommonResponse装饰FastAPI路由响应模型
实现FastAPI统一响应格式的泛型Pydantic模型
完全可以通过Pydantic的GenericModel实现这种通用响应格式,下面是具体的实现步骤和示例:
1. 导入依赖
首先导入所需的模块:
from fastapi import FastAPI from pydantic import BaseModel, GenericModel, Field from typing import TypeVar, Generic, List, Optional from datetime import datetime
2. 定义泛型类型变量
创建一个泛型类型变量,用于接收业务数据模型的类型:
T = TypeVar('T')
3. 定义通用响应模型CommonResponse
继承GenericModel和Generic[T],添加统一字段,并将业务数据字段info指定为泛型类型:
class CommonResponse(GenericModel, Generic[T]): # 带默认值的日期字段,用default_factory确保每次生成新的时间戳 date: datetime = Field(default_factory=datetime.utcnow) # 可选的状态码,默认200 code: int = Field(default=200) # 可选的提示信息,默认成功 message: str = Field(default="success") # 存放业务数据的字段,类型为传入的泛型T info: Optional[T] = Field(default=None)
4. 定义业务模型示例
比如你的Entry模型:
class Entry(BaseModel): id: int title: str content: str
5. 在FastAPI路由中使用
直接在路由的response_model参数中传入CommonResponse[Entry]或CommonResponse[List[Entry]]即可:
app = FastAPI() # 返回单个Entry的响应 @app.get("/entry/{entry_id}", response_model=CommonResponse[Entry]) def get_entry(entry_id: int): # 模拟从数据库获取数据 entry = Entry(id=entry_id, title="测试标题", content="测试内容") # 直接返回包含info的字典,FastAPI会自动按response_model序列化 return {"info": entry} # 返回Entry列表的响应 @app.get("/entries", response_model=CommonResponse[List[Entry]]) def get_entries(): entries = [ Entry(id=1, title="标题1", content="内容1"), Entry(id=2, title="标题2", content="内容2") ] return {"info": entries}
注意事项
date字段使用default_factory=datetime.utcnow而不是直接赋值datetime.utcnow(),这样可以避免所有响应共享同一个初始时间戳。- 如果需要处理异常场景,可以创建继承自
CommonResponse的子类,修改code和message的默认值,比如ErrorResponse。 - 返回数据时,既可以直接返回包含
info键的字典,也可以实例化CommonResponse对象返回(比如return CommonResponse(info=entry)),两种方式都能被FastAPI正确序列化。
内容的提问来源于stack exchange,提问作者Maxim Kolodnikov
相关产品推荐
相关产品推荐

