导读:本期聚焦于小伙伴创作的《pydantic v2 如何自定义字段验证器(field_validator vs field_serializer)?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《pydantic v2 如何自定义字段验证器(field_validator vs field_serializer)?》有用,将其分享出去将是对创作者最好的鼓励。

pydantic v2作为Python中主流的数据校验与模型定义库,提供了灵活的字段自定义处理能力,其中field_validator和field_serializer是最常用的两个装饰器,二者分别承担数据校验和序列化转换的职责,功能和使用场景有明显差异。

pydantic v2 如何自定义字段验证器(field_validator vs field_serializer)?

field_validator:字段校验装饰器

field_validator用于在模型实例化阶段对输入字段的值进行校验和预处理,当输入数据不符合要求时可以抛出校验错误,也可以对输入值做格式化处理后再赋值给字段。

基础使用方式

使用field_validator装饰器时需要指定要校验的字段名称,装饰器函数的第一个参数是cls,第二个参数是要校验的字段值,函数返回处理后的字段值。

from pydantic import BaseModel, field_validator, ValidationError

class UserModel(BaseModel):
    username: str
    age: int

    @field_validator("username")
    def check_username(cls, value):
        # 校验用户名长度
        if len(value) < 3:
            raise ValueError("用户名长度不能小于3位")
        # 去除首尾空格
        return value.strip()

    @field_validator("age")
    def check_age(cls, value):
        if value < 0 or value > 120:
            raise ValueError("年龄必须在0到120之间")
        return value

# 测试正常数据
try:
    user = UserModel(username="  test  ", age=25)
    print(user.username)  # 输出 test
    print(user.age)       # 输出 25
except ValidationError as e:
    print(e)

# 测试异常数据
try:
    user = UserModel(username="ab", age=150)
except ValidationError as e:
    print(e)

多字段校验与模式配置

field_validator支持同时校验多个字段,也可以通过mode参数配置校验触发时机,默认mode为before,即在类型转换前执行校验。

from pydantic import BaseModel, field_validator

class ProductModel(BaseModel):
    price: float
    discount: float

    @field_validator("price", "discount")
    def check_positive(cls, value):
        if value < 0:
            raise ValueError("价格和折扣不能为负数")
        return value

    @field_validator("discount", mode="after")
    def check_discount_lt_price(cls, value, info):
        # after模式下可以获取其他字段的值
        if info.data.get("price") and value > info.data["price"]:
            raise ValueError("折扣不能大于商品价格")
        return value

# 测试校验逻辑
product = ProductModel(price=100.0, discount=30.0)
print(product.discount)  # 输出 30.0

field_serializer:字段序列化装饰器

field_serializer用于在模型序列化阶段(比如调用model_dump、model_dump_json方法时)对字段值进行转换处理,不会影响模型实例化时的字段值,只影响输出结果。

基础使用方式

field_serializer装饰器同样需要指定要处理的字段名称,装饰器函数的第一个参数是字段值,返回序列化后的结果。

from pydantic import BaseModel, field_serializer
from datetime import datetime

class OrderModel(BaseModel):
    order_id: str
    create_time: datetime

    @field_serializer("create_time")
    def serialize_time(self, value):
        # 将datetime转换为指定格式的字符串
        return value.strftime("%Y-%m-%d %H:%M:%S")

    @field_serializer("order_id")
    def serialize_order_id(self, value):
        # 给订单号添加前缀
        return f"ORD_{value}"

order = OrderModel(
    order_id="123456",
    create_time=datetime(2024, 5, 20, 14, 30, 0)
)
# 序列化输出
print(order.model_dump())
# 输出 {'order_id': 'ORD_123456', 'create_time': '2024-05-20 14:30:00'}
print(order.model_dump_json())
# 输出 {"order_id":"ORD_123456","create_time":"2024-05-20 14:30:00"}

序列化时的上下文控制

field_serializer支持通过context参数传递序列化上下文,实现不同场景下的差异化序列化逻辑。

from pydantic import BaseModel, field_serializer

class ArticleModel(BaseModel):
    title: str
    content: str

    @field_serializer("content")
    def serialize_content(self, value, info):
        # 根据上下文判断是否截断内容
        context = info.context
        if context and context.get("is_summary"):
            return value[:50] + "..." if len(value) > 50 else value
        return value

article = ArticleModel(
    title="pydantic教程",
    content="这是一篇关于pydantic v2自定义字段处理的详细教程,内容包含field_validator和field_serializer的用法"
)
# 普通序列化
print(article.model_dump())
# 带上下文的序列化
print(article.model_dump(context={"is_summary": True}))

field_validator与field_serializer的核心区别

两者虽然都是字段处理的装饰器,但适用场景和功能有本质不同,具体差异如下:

对比维度field_validatorfield_serializer
触发时机模型实例化、字段赋值阶段模型序列化(model_dump、model_dump_json)阶段
核心作用校验输入数据合法性,预处理输入值转换字段输出格式,适配不同输出场景
是否影响原字段值会,返回的处理后值会赋给字段不会,仅影响序列化输出结果
错误处理校验失败抛出ValidationError序列化失败抛出序列化相关错误
典型场景数据格式校验、类型转换、取值范围校验时间格式化、字段加密、输出内容截断

组合使用场景示例

在实际开发中,经常需要同时使用两个装饰器完成完整的数据处理流程,比如下面的用户模型,既需要校验邮箱格式,又需要在输出时脱敏处理。

from pydantic import BaseModel, field_validator, field_serializer
import re

class UserProfileModel(BaseModel):
    email: str

    @field_validator("email")
    def validate_email(cls, value):
        # 校验邮箱格式
        pattern = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$"
        if not re.match(pattern, value):
            raise ValueError("邮箱格式不正确")
        return value

    @field_serializer("email")
    def serialize_email(self, value):
        # 邮箱脱敏处理,保留前3位和域名部分
        prefix, domain = value.split("@")
        masked_prefix = prefix[:3] + "***"
        return f"{masked_prefix}@{domain}"

# 测试完整流程
user = UserProfileModel(email="test123@ippipp.com")
print(user.email)  # 输出 test123@ippipp.com(原字段值不变)
print(user.model_dump())  # 输出 {'email': 'tes***@ippipp.com'}(序列化后脱敏)

通过合理搭配field_validator和field_serializer,可以满足pydantic v2中绝大多数自定义字段处理的需求,让数据模型的校验和输出逻辑更加清晰可控。

pydantic_v2field_validatorfield_serializer自定义字段验证修改时间:2026-06-14 19:54:39

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