I have a List
in a pydantic model. I'd like my custom validator to run when the list changes (not only on assignment).
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
I'd like that last append
to raise an error.
I'll get an error if i try to recreate the object (as expected)
A(**a.dict())
Even appending a wrong type is allowed. Why doesn't this break the model?
a.b.append("asdf") # no error
This is similar/an extension to: How to validate a pydantic object after editing it
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
I suggest two ways to evaluate the list, one is to use a validator to run when the list changes and the other is to use the field option as follows:
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="")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.