You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:17:38