如何验证 pydantic 中的复杂列表类型?

How to validate complex list types in pydantic?

为什么 pydantic 不验证作为 Foo 对象列表的参数,但在参数是原始类型列表时抛出 ValidationError?

我可以强制验证复杂类型吗?

验证无效:

from typing import List
from pydantic import BaseModel


class Foo(BaseModel):
    kind: str = "foo"

class Bar(BaseModel):
    kind: str = "bar"

class Spam(BaseModel):
    foos: List[Foo]

spam = Spam(foos=[Bar()])
print(spam.dict())

>>> {'foos': [{'kind': 'bar'}]}

验证工作:

class Spam(BaseModel):
    foos: List[int]


spam = Spam(foos=[Bar()])
print(spam.dict())

pydantic.error_wrappers.ValidationError: 1 validation error for Spam
foos -> 0
  value is not a valid integer (type=type_error.integer)

您无法验证 kind: str = "foo" 之类的值。您必须使用 Field 来验证变量的值。

尝试:

from typing import List

import pydantic
from pydantic import BaseModel, Field


class Foo(BaseModel):
   kind: str = Field(const="foo", default="foo")

class Bar(BaseModel):
    kind: str = Field(const="bar", default="bar")

class Spam(BaseModel):
    foos: List[Foo]

try:
    Spam.parse_obj({'foos': [{'kind': 'bar'}]})
except pydantic.ValidationError as e:
    print(e)

使用pydantic时,应记住that:

pydantic is primarily a parsing library, not a validation library. Validation is a means to an end: building a model which conforms to the types and constraints provided.

In other words, pydantic guarantees the types and constraints of the output model, not the input data.

为了对传入数据进行额外验证,提供了一个工具 - validators。 例如:

class Spam(BaseModel):
    foos: List[Foo]

    @validator('foos', pre=True, each_item=True)
    def check_squares(cls, v):
        assert isinstance(v, Foo), "Foo is only allowed"
        return v