pydantic 如何用 field_validator 实现依赖字段校验

来源:站长站作者:乙爱丽丝头衔:网络博主
导读:本期聚焦于小伙伴创作的《pydantic 如何用 field_validator 实现依赖字段校验》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《pydantic 如何用 field_validator 实现依赖字段校验》有用,将其分享出去将是对创作者最好的鼓励。

在pydantic的数据模型校验场景中,依赖字段校验指的是一个字段的校验规则需要参考同模型中其他字段的取值,比如当字段A的取值为特定值时,字段B需要满足对应的格式要求。field_validator作为pydantic核心的校验装饰器,完全可以支持这类场景的实现。

pydantic 如何用 field_validator 实现依赖字段校验

field_validator 基本用法回顾

field_validator是pydantic.model_validator之外的字段级校验工具,主要用于对指定字段的入参进行校验,基础用法是装饰一个类方法,方法接收字段值作为参数,返回校验后的值或者抛出异常。

基础的单字段校验示例如下:

from pydantic import BaseModel, field_validator, ValidationError

class User(BaseModel):
    age: int

    @field_validator("age")
    def check_age(cls, v):
        if v < 0:
            raise ValueError("年龄不能为负数")
        return v

# 测试正常情况
user = User(age=18)
print(user.age)  # 输出 18

# 测试异常情况
try:
    User(age=-5)
except ValidationError as e:
    print(e)

依赖字段校验的核心思路

field_validator本身接收的是单个字段的值,要实现依赖其他字段的校验,需要在校验方法中获取到整个模型的数据。pydantic的field_validator装饰的校验方法,除了接收字段值之外,还可以通过info参数获取到当前校验的上下文信息,其中包含已经校验过的其他字段的值。

需要注意的是,field_validator的校验顺序默认是按照字段在模型中定义的顺序执行的,因此如果要在一个字段的校验中依赖另一个字段的值,被依赖的字段需要定义在该字段之前,否则可能无法获取到对应的值。

具体实现示例

示例1:基础依赖字段校验

假设我们有个订单模型,当订单类型是"预售"时,预售发货时间必须晚于当前时间,其他订单类型不需要校验该字段。这里pre_sale_time字段的校验依赖order_type字段的值。

from pydantic import BaseModel, field_validator, ValidationError
from datetime import datetime

class Order(BaseModel):
    order_type: str
    pre_sale_time: datetime | None = None

    @field_validator("pre_sale_time")
    def check_pre_sale_time(cls, v, info):
        # 从info.data中获取已经校验过的order_type字段值
        order_type = info.data.get("order_type")
        if order_type == "预售":
            if v is None:
                raise ValueError("预售订单必须填写预售发货时间")
            if v < datetime.now():
                raise ValueError("预售发货时间必须晚于当前时间")
        return v

# 测试正常预售订单
order1 = Order(
    order_type="预售",
    pre_sale_time=datetime(2024, 12, 31)
)
print(order1.order_type, order1.pre_sale_time)

# 测试非预售订单,不需要填写预售时间
order2 = Order(order_type="现货")
print(order2.order_type, order2.pre_sale_time)

# 测试异常情况:预售订单未填发货时间
try:
    Order(order_type="预售")
except ValidationError as e:
    print(e)

示例2:多字段联动校验

再来看一个更复杂的场景,用户注册模型中,当用户选择"企业用户"类型时,必须填写企业名称,且企业名称长度不能小于4个字符,个人用户则不需要填写企业名称。

from pydantic import BaseModel, field_validator, ValidationError

class RegisterForm(BaseModel):
    user_type: str
    company_name: str | None = None

    @field_validator("company_name")
    def check_company_name(cls, v, info):
        user_type = info.data.get("user_type")
        if user_type == "企业用户":
            if v is None or v.strip() == "":
                raise ValueError("企业用户必须填写企业名称")
            if len(v.strip()) < 4:
                raise ValueError("企业名称长度不能小于4个字符")
        else:
            # 非企业用户清空企业名称字段
            return None
        return v.strip()

# 测试正常企业用户注册
form1 = RegisterForm(user_type="企业用户", company_name="测试科技有限公司")
print(form1.user_type, form1.company_name)

# 测试个人用户注册
form2 = RegisterForm(user_type="个人用户", company_name="随便填")
print(form2.user_type, form2.company_name)  # 输出 个人用户 None

# 测试异常情况:企业用户企业名称过短
try:
    RegisterForm(user_type="企业用户", company_name="测试")
except ValidationError as e:
    print(e)

注意事项

  • 字段定义顺序:被依赖的字段必须定义在依赖字段之前,否则info.data中可能获取不到对应的值,因为pydantic默认按字段定义顺序执行field_validator校验。
  • info参数的使用:field_validator的校验方法需要显式声明info参数才能获取到上下文数据,info是pydantic.ValidationInfo类型的实例,除了data属性外还包含其他校验上下文信息。
  • 校验失败提示:可以通过抛出ValueError自定义校验失败的提示信息,pydantic会将这些异常包装成ValidationError返回给调用方。
  • 多字段校验:如果需要同时校验多个字段的依赖关系,也可以在field_validator中传入多个字段名,不过更推荐的方式是对依赖字段单独做校验,逻辑会更清晰。

总结

通过field_validator实现依赖字段校验的核心是利用info.data获取同模型中其他已校验字段的值,结合字段定义顺序保证依赖字段先被校验,就可以在单个字段的校验逻辑中完成跨字段的联动校验。这种方式不需要额外使用model_validator,逻辑更聚焦在单个字段的校验规则上,代码可读性和维护性都更好。

pydanticfield_validator依赖字段校验数据验证修改时间:2026-06-24 10:24:47

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。