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

如何为嵌套Pydantic模型字段设置默认值?

为嵌套Pydantic V2字段设置默认值

问题场景

通过datamodel-codegen从以下JSON数据生成Pydantic V2模型后,需要给嵌套的state字段设置默认值NY:

{
    "name": "Alice",
    "age": 30,
    "addresses": [
        {
            "street": "123 Main St",
            "city": "New York",
            "state": "NY"
        },
        {
            "street": "456 Elm St",
            "city": "Los Angeles"
        }
    ]
}

生成的初始模型如下:

from typing import List, Optional
from pydantic import BaseModel

class AddressesItem(BaseModel):
    street: str
    city: str
    # 需要将state默认值设为NY
    state: Optional[str] = None

class Model(BaseModel):
    name: str
    age: int
    addresses: List[AddressesItem]

尝试直接继承Model并添加字段验证器失败:

from pydantic import field_validator

class MyModel(Model):
    class ConfigDict:
        validate_assignment = True

    @field_validator("state") # 加check_fields=False仍报错
    def set_value(cls, state):
        return state or 'NY'

错误信息:

pydantic.errors.PydanticUserError: Decorators defined with incorrect fields: schema.MyModel:51085136.set_value (use check_fields=False if you're inheriting from the model and intended this

正规解决方案

方案1:基于Pydantic继承的正确修改方式

state是AddressesItem类的字段,而非Model的字段,因此需要针对嵌套类做扩展,再替换父模型中的对应字段类型:

方式A:直接重写字段默认值

这是最简洁的方式,直接扩展嵌套类并覆盖字段默认值:

from typing import List, Optional
from pydantic import BaseModel

# 原始生成的模型
class AddressesItem(BaseModel):
    street: str
    city: str
    state: Optional[str] = None

class Model(BaseModel):
    name: str
    age: int
    addresses: List[AddressesItem]

# 扩展嵌套类,设置state默认值为NY
class MyAddressesItem(AddressesItem):
    state: Optional[str] = "NY"

# 继承父模型,替换addresses的类型为扩展后的嵌套类
class MyModel(Model):
    addresses: List[MyAddressesItem]

方式B:使用字段验证器(适合动态默认值场景)

如果需要基于逻辑动态设置默认值,可使用字段验证器:

from typing import List, Optional
from pydantic import BaseModel, field_validator

# 原始生成的模型
class AddressesItem(BaseModel):
    street: str
    city: str
    state: Optional[str] = None

class Model(BaseModel):
    name: str
    age: int
    addresses: List[AddressesItem]

# 扩展嵌套类,添加验证器设置默认值
class MyAddressesItem(AddressesItem):
    @field_validator("state", mode="before")
    def set_default_state(cls, value):
        # 当value为None或空字符串时,返回默认值NY
        return value or "NY"

class MyModel(Model):
    addresses: List[MyAddressesItem]

方案2:通过datamodel-codegen直接生成带默认值的模型

datamodel-codegen支持基于JSON Schema生成模型,可先将原始JSON转换为带默认值的JSON Schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "name": {"type": "string"},
    "age": {"type": "integer"},
    "addresses": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "street": {"type": "string"},
          "city": {"type": "string"},
          "state": {"type": "string", "default": "NY"}
        },
        "required": ["street", "city"]
      }
    }
  },
  "required": ["name", "age", "addresses"]
}

执行以下命令生成模型:

datamodel-codegen --input schema.json --output model.py --output-model-type pydantic_v2.BaseModel

生成的AddressesItem类中,state字段会自动带有默认值NY。

内容的提问来源于stack exchange,提问作者shaik moeed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:41:38