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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:33:24