【问题标题】:How to validate complex list types in pydantic?如何验证 pydantic 中的复杂列表类型?
【发布时间】:2021-08-14 10:55:39
【问题描述】:

为什么 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)

【问题讨论】:

    标签: python validation pydantic


    【解决方案1】:

    使用pydantic时,应记住that

    pydantic 主要是一个解析库,不是验证库。验证是达到目的的一种手段:构建一个符合所提供的类型和约束的模型。

    换句话说,pydantic 保证输出模型的类型和约束,而不是输入数据

    对于传入数据的额外验证,提供了一个工具 - 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
    

    【讨论】:

      【解决方案2】:

      您无法验证 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)
      

      【讨论】:

      • 这很好,但不是我想要的。当 foos 参数是包含类型不是 Foo 的项目的列表时,我希望 pydantic 引发 ValidationError。
      • 您无法区分 Foo 和 Bar,因为它们都包含变量 kind。您可以将类型更改为foobar,它会抛出验证错误。
      猜你喜欢
      • 2022-11-02
      • 2021-01-22
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 1970-01-01
      • 2021-09-06
      • 2020-08-07
      • 1970-01-01
      相关资源
      最近更新 更多