FastAPI中如何正确编写Pydantic BaseModel实现预期响应结构
问题根因
- 模型层级定义错误:所有术式相关的数值字段被同时定义在
ResponseModel根层级、以及data的示例结构中,序列化时同名字段会在根节点和data节点各返回一次,造成重复。 - 字段参数使用错误:
Field()中传入的title参数是OpenAPI文档的字段说明属性,不是字段默认值,原写法没有给字段指定有效默认值。 - 类型约束缺失:
data字段声明为object类型,没有做结构化校验,序列化时会透传所有传入的数据库查询字段,无法过滤多余数据。 - 空值序列化规则未配置:
Optional类型字段未赋值时默认返回null,没有配置排除空值的规则。
正确实现代码
from typing import Optional from pydantic import BaseModel, Field # 单独定义data区块的结构化模型,收敛所有data下的字段 class SurgeryData(BaseModel): custom_lasik: Optional[float] = Field(default=0.0, title="个性化LASIK数值") custom_lasek: Optional[float] = Field(default=0.0, title="个性化LASEK数值") lasik: Optional[float] = Field(default=0.0, title="LASIK数值") lasek: Optional[float] = Field(default=0.0, title="LASEK数值") smile_lasik: Optional[float] = Field(default=0.0, title="全飞秒LASIK数值") toric: Optional[float] = Field(default=0.0, title="Toric晶体数值") normal: Optional[float] = Field(default=0.0, title="常规术式数值") class Config: # 序列化时自动排除值为None的字段,不会返回null exclude_none = True class ResponseModel(BaseModel): code: int = Field(default=200, title="响应状态码") message: str = Field(default="success", title="响应消息") data: SurgeryData # 用结构化模型替换无约束的object类型 class Config: schema_extra = { "example": { "code": 200, "message": "success", "data": { "custom_lasik": 0.0, "custom_lasek": 0.0, "lasik": 0.5, "lasek": 0.35, "smile_lasik": 0.15, "toric": 0.0, "normal": 0.0 } } }
可选全局配置
如果需要项目内所有接口都默认不返回null值,可以在FastAPI实例初始化时添加全局配置,不用每个模型单独写exclude_none:
from fastapi import FastAPI app = FastAPI( # 全局配置所有响应模型序列化时排除None值 response_model_exclude_none=True )
注意事项
- 所有属于
data节点的字段必须全部收敛到SurgeryData模型中,禁止在ResponseModel根层级重复声明同名字段,从结构上避免字段重复返回。 - 替换
data的object类型为结构化模型后,Pydantic会自动过滤掉传入的数据库查询结果中未在模型中声明的多余字段,不会出现无关字段泄露的问题。 Field()的默认值必须通过default参数指定,title、description等参数仅用于OpenAPI文档展示,不影响字段实际序列化逻辑。
内容的提问来源于stack exchange,提问作者Tae In Kim
相关产品推荐
相关产品推荐

