如何在Pydantic验证器中获取字段类型并统一处理验证失败?
在Pydantic中用全局验证器实现验证失败字段赋值None
问题描述
我希望在Pydantic中为验证失败的字段自动赋值None,并且想用一个全局验证器处理多个字段。使用validate_model(model, raw_data)方法时需要知道当前字段对应的模型,请问有没有办法在全局验证器(@validator('*'))中获取当前被验证字段的类型?
示例代码框架:
@validator('*', pre=True) def validate_name(cls, value: str): model_of_field = ..... # 获取字段类型的方法 data, fields_set, e = validate_model(model_of_field, value) return value
解决方案
可以通过在验证器函数中添加field参数(类型为pydantic.fields.ModelField)获取当前字段的元数据,进而解析出字段对应的模型类型。需要注意处理Optional这类泛型包装的情况,提取出实际的模型类。
修改后的完整代码
from typing import Any, Optional, get_args, get_origin from pydantic import BaseModel, validator, validate_model, ModelField class NameModel(BaseModel): name: str class AgeModel(BaseModel): age: int class MyModel(BaseModel): name_data: Optional[NameModel] age_data: Optional[AgeModel] @classmethod def pre_validate_any_field_and_return_none_on_validation_error(cls, model: Any, value: Any): data, fields_set, e = validate_model(model, value) return None if e else value @validator('*', pre=True) def validate_all_fields(cls, value: Any, field: ModelField): # 处理Optional类型,提取内部实际模型 field_type = field.type_ origin = get_origin(field_type) if origin is Optional: model_of_field = get_args(field_type)[0] else: model_of_field = field_type return cls.pre_validate_any_field_and_return_none_on_validation_error(model_of_field, value) my_data = { 'name_data': {'name1': 'Hello_a'}, # 字段名错误,验证失败返回None 'age_data': {'age': 120} # 验证通过保留数据 } my_object: MyModel = MyModel(**my_data) print(my_object) # 输出: name_data=None age_data=AgeModel(age=120)
关键说明
field参数的作用:在全局验证器中添加field: ModelField参数后,Pydantic会自动传入当前被验证字段的元数据对象,包含字段的类型、名称等信息。- 解析泛型类型:因为字段声明为
Optional[NameModel],需要用get_origin和get_args从typing模块中提取出实际的模型类(NameModel),而不是直接使用field.type_(它会是Optional[NameModel])。 - 验证逻辑复用:通过提取模型类型,就可以复用统一的验证逻辑,不用为每个字段单独编写验证器。
内容的提问来源于stack exchange,提问作者RaamEE
相关产品推荐
相关产品推荐

