You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pydantic模型中用@validator校验日期先后顺序?

问题分析与解决方案

你的代码存在几个关键问题导致校验不生效:

  1. 校验顺序错误:startFrom在StartTo之前定义,Pydantic默认按字段定义顺序执行校验,校验startFrom时StartTo还未完成解析,因此values中没有StartTo,直接跳过了核心校验逻辑。
  2. Optional字段配置矛盾:你给Optional字段设置了...(必填标记),这会让字段变成必填,和Optional的定义冲突,正确的默认值应该是None。
  3. 未处理StartTo为None的情况:即使StartTo存在于values中,若值为None,直接比较startFrom > None会引发错误,且这种场景无需校验。

修正方案(分Pydantic版本)

方案1:Pydantic v1 使用root_validator

root_validator会在所有字段解析完成后执行,能确保拿到两个字段的最终值:

from pydantic import BaseModel, Field, root_validator
from typing import Optional
from datetime import date

class MyModel(BaseModel):
    startFrom: Optional[date] = Field(
        None,  # Optional字段默认值设为None
        description='XXX',
        example='2023-03-15',
    )

    StartTo: Optional[date] = Field(
        None,
        description='XXX',
        example='2023-03-31',
    )

    otherData: str = Field(
        ...,
        description='XXX',
        example='XX',
    )

    @root_validator(skip_on_failure=True)
    def check_date_order(cls, values):
        start_from = values.get('startFrom')
        start_to = values.get('StartTo')
        # 仅当两个字段都不为空时执行校验
        if start_from is not None and start_to is not None:
            if start_from > start_to:
                raise ValueError('startFrom must be earlier than StartTo')
        return values

方案2:Pydantic v2 使用model_validator

v2中root_validator被弃用,改用model_validator:

from pydantic import BaseModel, Field, model_validator
from typing import Optional
from datetime import date

class MyModel(BaseModel):
    startFrom: Optional[date] = Field(
        None,
        description='XXX',
        example='2023-03-15',
    )

    StartTo: Optional[date] = Field(
        None,
        description='XXX',
        example='2023-03-31',
    )

    otherData: str = Field(
        ...,
        description='XXX',
        example='XX',
    )

    @model_validator(mode='after')
    def check_date_order(self):
        if self.startFrom is not None and self.StartTo is not None:
            if self.startFrom > self.StartTo:
                raise ValueError('startFrom must be earlier than StartTo')
        return self

额外说明

  • 若使用FastAPI等框架,当Pydantic抛出ValidationError时,框架会自动返回422状态码,无需额外处理。
  • 建议统一字段命名风格(比如把StartTo改为startTo),避免大小写混淆引发的隐性问题。

内容的提问来源于stack exchange,提问作者Da sil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:13:11