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

FastAPI(Pydantic)中如何保持请求体结构与BaseModel定义一致?

问题

在POST请求中,希望无论用户传入什么内容,请求体都严格遵循BaseModel的定义。

示例BaseModel定义如下:

from typing import Optional
from pydantic import BaseModel

class Address(BaseModel):
    city: Optional[str]
    state: Optional[str]
    pinCode: Optional[str]

class User_ReqModel(BaseModel):
    name: str
    mobile: Optional[str]
    address: Optional[Address]

当请求体为{"name": "Amit Pathak"}时,访问User_ReqModel.address.city会报错——因为请求体中未传入address,此时该字段值为None,无法直接访问子属性。

目前有两种规避方式,但均存在不足:

  • 对空值逐一检查不可行,因为请求体结构较大,无法覆盖所有属性;
  • 转成dict()后用.get('key', {})取值,这种方式不够简洁,希望避免。

期望实现:当请求体为{"name": "Amit Pathak"}时,自动生成如下格式的实例:

{
    "name": "Amit Pathak",
    "mobile": null,
    "address": {
        "city": null,
        "state": null,
        "pinCode": null
    }
}

解决方案

只需修改BaseModel的字段定义,给嵌套模型字段设置默认工厂函数,让缺失字段时自动生成空模型实例,同时给Optional类型字段显式设置默认值None(Pydantic对Optional类型会自动处理,但显式设置更清晰)。

修改后的代码

from typing import Optional
from pydantic import BaseModel, Field

class Address(BaseModel):
    city: Optional[str] = None
    state: Optional[str] = None
    pinCode: Optional[str] = None

class User_ReqModel(BaseModel):
    name: str
    mobile: Optional[str] = None
    # 用default_factory自动生成空的Address实例
    address: Address = Field(default_factory=Address)

关键说明

  • Address的每个字段显式设置None为默认值,确保未传入时自动填充为null;
  • 将User_ReqModel的address字段类型从Optional[Address]改为Address,并通过default_factory=Address指定:当该字段缺失时,自动创建一个所有子字段为None的Address实例;
  • 处理后,即使请求体未传入mobile或address,实例也会自动填充对应默认值,直接访问user.address.city不会报错。

如果需要允许用户显式传入"address": null,可以保留Optional类型并搭配默认工厂:

class User_ReqModel(BaseModel):
    name: str
    mobile: Optional[str] = None
    address: Optional[Address] = Field(default_factory=Address)

这样既支持用户传入null,也会在字段缺失时自动生成空的Address实例。


内容的提问来源于stack exchange,提问作者Amit Pathak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:32:50