如何在FastAPI中统一响应格式并保留Pydantic数据模型?
解决方案
1. 定义泛型统一响应模型
用Pydantic的泛型特性创建通用响应结构,既能统一格式,又能让Swagger识别data字段的具体模型:
Pydantic v2 实现:
from typing import Generic, TypeVar, Optional from pydantic import BaseModel, ConfigDict T = TypeVar('T') class ApiResponse(BaseModel, Generic[T]): model_config = ConfigDict(from_attributes=True) # 支持从ORM实例解析 code: int = 0 msg: str = "success" data: Optional[T] = None
Pydantic v1 实现:
from typing import Generic, TypeVar, Optional from pydantic import BaseModel T = TypeVar('T') class ApiResponse(BaseModel, Generic[T]): class Config: orm_mode = True # 支持从ORM实例解析 code: int = 0 msg: str = "success" data: Optional[T] = None
2. 配置User模型支持ORM转换
你的User Pydantic模型必须开启ORM模式,这样SQLAlchemy查询返回的实例才能直接被解析为Pydantic模型:
Pydantic v2:
from pydantic import BaseModel, ConfigDict class User(BaseModel): model_config = ConfigDict(from_attributes=True) id: str name: str # 其他业务字段...
Pydantic v1:
from pydantic import BaseModel class User(BaseModel): class Config: orm_mode = True id: str name: str # 其他业务字段...
3. 路由中使用统一响应模型
在路由上指定response_model=ApiResponse[User],返回时把SQLAlchemy实例直接传入ApiResponse的data参数:
@router.get("/1", response_model=ApiResponse[User]) def read_user(db: Session = Depends(get_db)): db_user = user_module.get_user(db, user_id="1") if db_user is None: raise HTTPException(status_code=404, detail="User not found") return ApiResponse(data=db_user)
这样Swagger会自动生成包含User结构的文档,返回格式也严格符合你要的{"code":0,"msg":"success","data":{...}}。
4. 统一异常响应格式
为了让错误请求也返回统一格式,自定义异常处理器捕获HTTPException和全局异常:
from fastapi import Request, HTTPException from fastapi.responses import JSONResponse # 处理HTTP异常(如404、400) @router.exception_handler(HTTPException) async def http_exception_handler(request: Request, exc: HTTPException): return JSONResponse( status_code=exc.status_code, content={"code": exc.status_code, "msg": exc.detail, "data": None} ) # 处理全局未知异常 @router.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): return JSONResponse( status_code=500, content={"code": 500, "msg": "Internal Server Error", "data": None} )
方案优势
- 解决了中间件方案无法在Swagger中展示具体
data模型的问题,泛型模型能让文档自动识别返回结构。 - 通过Pydantic的ORM模式,直接把SQLAlchemy实例转成目标Pydantic模型,无需手动转换。
- 异常处理器确保所有响应(成功/失败)格式统一,前端无需区分处理逻辑。
内容的提问来源于stack exchange,提问作者XiaomaiTX
相关产品推荐
相关产品推荐

