python 当列表项在pydantic模型中改变时,如何验证它们?

vktxenjb  于 2022-11-21  发布在  Python
关注(0)|答案(2)|浏览(207)

我有一个pydantic模型中的List,我希望我的自定义验证器在列表改变时运行(不仅仅是在赋值时)。

from typing import List
from pydantic import BaseModel, validator

class A(BaseModel):
    b: List[int] = []

    class Config:
        validate_assignment = True

    @validator("b")
    def positive(cls, v):
        assert all(i > 0 for i in v), f"No negative numbers: {v}"
        return v

a = A()

a.b = [1, 2, -3]  # error

a.b = [1, 2]  # no error
a.b.append(-3)  # no error

我希望最后一个append引发错误。
如果我尝试重新创建对象,则会出现错误(如预期)

A(**a.dict())

即使附加错误的类型也是允许的,为什么这不会破坏模型呢?

a.b.append("asdf")  # no error

这类似于/是以下内容的扩展:How to validate a pydantic object after editing it

krcsximq

krcsximq1#

from pydantic import BaseModel, validator
from typing import List

class PositiveIntList(BaseModel):
    __root__: List[int] = []

    def append(self, value: int) -> None:
        self.__root__.append(value)
        super().__init__(__root__=self.__root__)

    def __getitem__(self, item: int) -> int:
        return self.__root__[item]

    def __setitem__(self, item: int, value: int) -> None:
        self.__root__[item] = value
        super().__init__(__root__=self.__root__)

    @validator("__root__", each_item=True)
    def positive(cls, v):
        assert v > 0, f"No negative numbers: {v}"
        return v

class A(BaseModel):
    b: PositiveIntList = PositiveIntList()

a = A(b=[1, 2, 3])
a = A(b=[1, 2, -3])  # error

a.b = PositiveIntList.parse_obj([4, 5])
a.b = PositiveIntList.parse_obj([4, -5])  # error

a.b.append(6)
a.b.append(-6)  # error

a.b[0] = 7
a.b[0] = -7  # error
cbwuti44

cbwuti442#

我建议两种方法来评估列表,一种是使用验证器在列表更改时运行,另一种是使用field选项,如下所示:

from typing import List
from pydantic import BaseModel, validator, Field

class A(BaseModel):
    b: List[int] = []

    class Config:
        validate_assignment = True

    @validator("b")
    def positive(cls, v):
        assert all(i > 0 for i in v), f"No negative numbers: {v}"
        return v

class A(BaseModel):
     b: List[int] = Field(ge=0, le=6, unique_items=True,description="")

相关问题