我的问题很简单,我很惊讶还没有人问过:
如何在pydantic中验证日期?
例如,我只想接受1980.1.1-2000.1.1范围内的日期。
datetime字段的验证器正是您所需要的。您可以按照以下方式使用它:
from pydantic import BaseModel, validator
from datetime import datetime
class DModel(BaseModel):
dt: datetime
@validator("dt")
def ensure_date_range(cls, v):
if not datetime(year=1980, month=1, day=1) <= v < datetime(year=2000, month=1, day=1):
raise ValueError("Must be in range")
return v
DModel.parse_obj({"dt": "1995-01-01T00:00"})
DModel.parse_obj({"dt": "2001-01-01T00:00"}) # validation error
一个常见的用例,可能是根据OP在复数中使用“日期”提示的,是在相同模型中验证多个日期。这个文档记录得很少,而且如果要解析其他日期格式的字符串,还有其他问题需要处理。
这不是在文档中明确说明的。好吧,它在那里,但需要时所述的情况并未提到。如果您需要验证器将非ISO str
格式转换为date
,Pydantic会在您的验证器运行之前发现无效的日期格式。在此情况下,仅应用多个验证器或将一个验证器应用于多个字段是不足够的,还需要提供pre=True
参数,以预先防止默认格式引发异常,然后才能进行验证:
from datetime import datetime, date
from pydantic import BaseModel, validator
def validate_date(value: str) -> date:
return datetime.strptime(value, "%d/%m/%Y").date()
class CommonModel(BaseModel):
created: date
modified: date
confirmed: date
closed: date
_validate_dates = validator(
'created', 'modified', 'confirmed', 'closed', pre=True, allow_reuse=True,
)(validate_date)
data = {
'created': '25/12/2000',
'modified': '31/12/2000',
'confirmed': '01/01/2001',
'closed': '11/09/2001',
}
try:
model = CommonModel(**data)
except Exception as e:
print(e.json())
关于这个问题的文档非常简略,我不得不自己发现这一点,而且我还没有找到其他人指出这一点,所以我认为在这里演示这种代码会很有帮助。
field_validator
代替validator
,将pre=True
改为mode='before'
,并且去掉allow_reuse
参数,应该可以适用于不同类型的其他字段。需要验证的字段的名称需要列出来,所以不要在不需要特定验证器的字段中放入字段名称。再次说明,这个部分的文档记录较少或者没有明确记录,这有点令人沮丧,但通过试错也不难弄清楚。我会更新答案以进行澄清。 - undefined