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

Pydantic嵌套JSON列表中Optional字段抛出‘Field required’问题求解

问题描述

使用Pydantic验证嵌套JSON数据时遇到字段验证问题,代码如下:

app_dict={'apps': [{'app_id': 'a_1',
   'group_id': '123',
   'report_id': '456',
   'principal_id': 'p_1'},
  {'app_id': 'a_2',
   'group_id': '789',
   'report_id': '987'}]}


class PbiApps(BaseModel):
    app_id: ty.Required[pty.StrictStr]
    group_id: ty.Required[pty.StrictStr]
    report_id: ty.Required[pty.StrictStr]
    principal_id: ty.Optional[pty.StrictStr]
 
class PbiMain(BaseModel):
    apps: ty.Optional[ty.List[PbiApps]]

解析为PbiMain(**app_dict)时,针对第二个app(a_2)抛出ValidationError:

ValidationError: 1 validation error for Settings
apps.1.principal_id
  Field required [type=missing, input_value={'app_id': 'a_2', '...test', 'report_id': '789'}, input_type=DictConfig]
    For further information visit https://errors.pydantic.dev/2.5/v/missing

已知设置principal_id: ty.Optional[pty.StrictStr] = None可解决问题,但希望验证通过后该字段不存在而非设为None,询问是否有实现方法。

解决方案

你可以通过以下几种方式实现需求:

方法一:序列化时排除None值字段

在定义字段时设置默认值None,调用model_dump()时传入exclude_none=True,自动移除值为None的字段:

from pydantic import BaseModel, StrictStr
import typing as ty

class PbiApps(BaseModel):
    app_id: ty.Required[StrictStr]
    group_id: ty.Required[StrictStr]
    report_id: ty.Required[StrictStr]
    principal_id: ty.Optional[StrictStr] = None
 
class PbiMain(BaseModel):
    apps: ty.Optional[ty.List[PbiApps]]

# 验证数据
main_obj = PbiMain(**app_dict)
# 序列化输出时剔除None值字段
result = main_obj.model_dump(exclude_none=True)
print(result['apps'][1])  # 输出: {'app_id': 'a_2', 'group_id': '789', 'report_id': '987'}

方法二:全局配置自动排除None值

如果希望所有模型实例序列化时都自动排除None值字段,可在模型类中添加model_config配置:

from pydantic import BaseModel, StrictStr
import typing as ty

class PbiApps(BaseModel):
    app_id: ty.Required[StrictStr]
    group_id: ty.Required[StrictStr]
    report_id: ty.Required[StrictStr]
    principal_id: ty.Optional[StrictStr] = None

    # 全局配置,序列化时自动排除None值字段
    model_config = {'exclude_none': True}
 
class PbiMain(BaseModel):
    apps: ty.Optional[ty.List[PbiApps]]
    model_config = {'exclude_none': True}

main_obj = PbiMain(**app_dict)
result = main_obj.model_dump()
print(result['apps'][1])  # 同样不会包含principal_id字段

方法三:自定义字段验证逻辑

如果需要在验证阶段就处理字段缺失的情况,可使用字段验证器灵活控制,再结合exclude_none实现输出要求:

from pydantic import BaseModel, StrictStr, field_validator
import typing as ty

class PbiApps(BaseModel):
    app_id: ty.Required[StrictStr]
    group_id: ty.Required[StrictStr]
    report_id: ty.Required[StrictStr]
    principal_id: ty.Optional[StrictStr]

    @field_validator('principal_id', mode='before')
    def handle_missing_principal(cls, value):
        # 字段缺失时返回None,后续通过配置排除
        return value if value is not None else None

    model_config = {'exclude_none': True}
 
class PbiMain(BaseModel):
    apps: ty.Optional[ty.List[PbiApps]]
    model_config = {'exclude_none': True}

main_obj = PbiMain(**app_dict)
result = main_obj.model_dump()
print(result['apps'][1])  # 输出不含principal_id字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:26:17