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
相关产品推荐
相关产品推荐

