使用Pydantic的condate验证日期小于今日时出现OpenAPI错误
问题
在FastAPI应用中尝试用Pydantic限制传入日期必须小于今日,发现Pydantic的condate类型带有lt参数,于是写了如下代码:
from datetime import date from pydantic import BaseModel, condate class RiskData(BaseModel): dob: condate(lt=date.today())
运行后出现OpenAPI验证错误:
File "pydantic\main.py", line 342, in pydantic.main.BaseModel.__init__ pydantic.error_wrappers.ValidationError: 2 validation errors for OpenAPI components -> schemas -> RiskData -> properties -> dob -> exclusiveMaximum value is not a valid float (type=type_error.float) components -> schemas -> RiskData -> $ref field required (type=value_error.missing)
已知可以用pydantic.validator实现该功能,但想了解能否通过condate简化代码。
解决方法
这个错误的根源是condate生成的类型在FastAPI生成OpenAPI文档时,会把日期类型的lt参数转换成exclusiveMaximum字段,但OpenAPI要求这个字段的值必须是数字(浮点数或整数),而date.today()是date对象,无法直接转为符合要求的数字格式,导致文档生成失败。
要通过condate实现需求,需要调整参数的传递方式,让lt的值在生成OpenAPI schema时能被正确解析,同时保证验证逻辑生效:
Pydantic v2 推荐写法
from datetime import date from pydantic import BaseModel, condate, Annotated class RiskData(BaseModel): dob: Annotated[date, condate(lt=lambda: date.today())]
或者用函数封装更清晰的逻辑:
from datetime import date from pydantic import BaseModel, condate, Annotated def get_current_date(): return date.today() class RiskData(BaseModel): dob: Annotated[date, condate(lt=get_current_date)]
Pydantic v1 兼容写法
如果使用Pydantic v1,可结合Field实现等价的日期限制:
from datetime import date from pydantic import BaseModel, Field class RiskData(BaseModel): dob: date = Field(..., lt=date.today())
上述写法既能通过Pydantic内置的日期验证逻辑实现“小于今日”的限制,又能让FastAPI正确生成OpenAPI文档,避免出现类型错误。
内容的提问来源于stack exchange,提问作者Mikhail Trunov
相关产品推荐
相关产品推荐

