Jupyter AI

21 自定义验证逻辑

📅 发表日期: 2024年8月18日

分类: 🚀Python FastAPI 入门

👁️阅读: --

在上一篇中,我们探讨了如何使用 Pydantic 进行数据验证与序列化。Pydantic 提供了强大的数据模型创建和验证功能,但在某些情况下,我们可能需要实现更复杂的验证逻辑。在这一节中,我们将介绍如何在 Pydantic 中定义自定义验证器,以实现符合我们业务逻辑的数据验证。

自定义验证器简介

Pydantic 中,我们可以通过定义自定义验证器来扩展基本的验证功能。这些验证器可以是类方法,也可以是实例方法,通常使用 @validator 装饰器来实现。

示例:基本自定义验证器

让我们首先来看一个简单的例子。假设我们有一个模型,要求用户提供一个年龄字段,年龄必须在 0 到 120 之间。我们可以通过自定义验证器来实现这一要求:

from pydantic import BaseModel, validator, ValidationError

class User(BaseModel):
    name: str
    age: int

    @validator('age')
    def validate_age(cls, v):
        if not (0 <= v <= 120):
            raise ValueError('Age must be between 0 and 120')
        return v

# 测试自定义验证器
try:
    user = User(name='Alice', age=25)
    print(user)
    
    user_invalid = User(name='Bob', age=130)  # 触发验证错误
except ValidationError as e:
    print(e)

在这个例子中,我们定义了一个 User 模型,并添加了一个名为 validate_age 的自定义验证器。该验证器接收字段值 v 作为参数,如果值不在有效范围内,则抛出 ValueError,这样 Pydantic 将会捕获这个错误并返回相应的验证错误信息。

多个字段之间的验证

有时候,我们需要验证多个字段之间的相互关系。例如,我们想要验证用户的出生年份是否合理,可以根据用户的年龄计算出一个出生年份,并进行检查。我们可以使用 @root_validator 对整个模型进行验证。

示例:多个字段验证

以下是一个关于验证出生年月是否合逻辑的示例:

from pydantic import BaseModel, validator, root_validator, ValidationError
from datetime import datetime

class User(BaseModel):
    name: str
    birth_year: int
    age: int

    @root_validator
    def check_age_and_birth_year(cls, values):
        birth_year = values.get('birth_year')
        age = values.get('age')
        
        current_year = datetime.now().year
        expected_birth_year = current_year - age
        
        if birth_year != expected_birth_year:
            raise ValueError('The birth year and age do not match.')
        
        return values

# 测试多个字段验证
try:
    user = User(name='Alice', birth_year=1998, age=25)  # 合法
    print(user)
    
    user_invalid = User(name='Bob', birth_year=1990, age=25)  # 触发验证错误
except ValidationError as e:
    print(e)

在这个例子中,我们使用 @root_validator 来检查 birth_yearage 这两个字段之间的关系。我们首先计算出根据年龄推算出的出生年份,然后与提供的 birth_year 字段进行对比。

处理复杂的数据结构

在处理复杂的数据结构时,可能需要对嵌套的模型进行自定义验证。Pydantic 支持嵌套模型,我们可以在父模型中对子模型的字段进行验证。

示例:嵌套模型验证

让我们看一个关于订单的例子,我们有一个 Order 模型,其中包含一个 User 模型:

from pydantic import BaseModel, validator, ValidationError

class User(BaseModel):
    name: str
    age: int

class Order(BaseModel):
    user: User
    total: float

    @validator('total')
    def validate_total(cls, v, values):
        if v < 0:
            raise ValueError('Total must be a positive value.')
        if values.get('user').age < 18 and v > 1000:
            raise ValueError('Users under 18 cannot make orders over 1000.')
        return v

# 测试嵌套模型验证
try:
    order = Order(user=User(name='Alice', age=19), total=500)
    print(order)
    
    order_invalid = Order(user=User(name='Bob', age=17), total=1500)  # 触发验证错误
except ValidationError as e:
    print(e)

在这个例子中,我们在 Order 模型中验证了订单的 total 字段,同时考虑了用户的年龄。若用户年龄小于 18 岁,则其订单总额不能超过 1000。

总结

自定义验证器在 Pydantic 中是一个非常强大的功能,允许我们定义复杂的验证逻辑以满足具体的业务需求。在本节中,我们探讨了如何使用 @validator@root_validator 实现单字段和多字段的验证,此外还讨论了如何对嵌套模型进行验证。

在下一篇中,我们将讨论错误处理的常见策略,以及如何优雅地处理和返回验证错误。这样一来,我们就能够为用户提供更好的反馈体验。希望大家在实际开发中能够灵活运用 Pydantic 的验证特性,编写出质量更高的代码!

🚀Python FastAPI 入门 (滚动鼠标查看)