Pydantic:根据其他字段的值在验证器中使字段None

2024-06-17 10:02:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我将pydanticBaseModel与这样的验证器一起使用:

from datetime import date
from typing import List, Optional
from pydantic import BaseModel, BaseConfig, validator

class Model(BaseModel):
    class Config(BaseConfig):
        allow_population_by_alias = True
        fields = {
            "some_date": {
                "alias": "some_list"
            }
        }
    some_date: Optional[date]
    some_list: List[date]

    @validator("some_date", pre=True, always=True)
    def validate_date(cls, value):
        if len(value) < 2: # here value is some_list
            return None
        return value[0] # return the first value - let's assume it's a date string

# This reproduces the problem
m = Model(some_list=['2019-01-03'])

我想根据some_list的值来计算some_date的值,并在满足某个条件时使其None。在

我的JSON从不包含字段some_date,它总是基于some_list填充,因此pre=True, always=True。但是,some_date的默认验证器将在我的自定义验证器之后运行,如果validate_date返回None,则验证程序将失败。在

有没有一种方法可以创建这样一个只由另一个计算的字段,并且仍然可以是Optional?在


Tags: fromimportnonetruedatereturnvaluesome
1条回答
网友
1楼 · 发布于 2024-06-17 10:02:53

我倾向于说,你这样做是不可能的。在

您正确地指出,date的默认验证器是在数据模型中的自定义validate_date之后调用的。相关的源代码可以找到here: pydantic.fields.py(截至2019年1月,git hash:19320bf)。显然,验证程序的级联不支持allow_none-模式,有关详细信息,请参见^{}。更具体地说,某个特定验证器的输出永远不会针对None进行测试,该测试在^{}的上游进行。在

从阅读文档和pydantic的来源来看,我倾向于说pydantic的验证机制目前对验证函数中的类型转换(list -> datelist -> NoneType)的支持非常有限。如果您的用例有很好的参数,您可能需要请求该特性here。在

不过,退一步讲,使用alias和标志allow_population_by_alias(无论如何,正如documentation中所述,这是不推荐的)的方法似乎有点过载。some_date只需要作为some_list[0] if len(some_list) >= 2 else None的快捷方式,但它永远不会独立于some_list进行设置。如果真的是这样,为什么不选择下面这个简单得多的选项呢?在

class Model(BaseModel):
    some_list: List[date] = ...

    @property 
    def some_date(self):
        return None if len(self.some_list) < 2 else self.some_list[0]

相关问题 更多 >