【问题标题】:Pydantic constr vs Field argsPydantic constr 与 Field args
【发布时间】:2022-01-19 19:08:39
【问题描述】:

我想知道有什么区别:

from pydantic import BaseModel, Field

class Person(BaseModel):
    name: str = Field(..., min_length=1)

还有:

from pydantic import BaseModel, constr

class Person(BaseModel):
    name: constr(min_length=1)

两者似乎都执行相同的验证(即使name 为空字符串时也会引发完全相同的异常信息)。这只是代码风格的问题吗?其中一个比另一个更受欢迎吗?

另外,如果我想包含一个非空字符串列表作为属性,您认为以下哪种方式更好?:

from typing import List
from pydantic import BaseModel, constr

class Person(BaseModel):
    languages: List[constr(min_length=1)]

或者:

from typing import List    
from pydantic import BaseModel, Field

class Person(BaseModel):
    languages: List[str]
    
    @validator('languages', each_item=True)
    def check_nonempty_strings(cls, v):
        if not v:
            raise ValueError('Empty string is not a valid language.')
        return v

编辑: FWIW,我将其用于 FastAPI 应用程序。

编辑2: 对于我的第二个问题,我认为第一个替代方案更好,因为它包括架构中的长度要求(因此它在文档中)

【问题讨论】:

    标签: python validation fastapi typing pydantic


    【解决方案1】:

    constr 和 Fields 的用途不同。

    constr 是一种特定类型,它提供有关此特定类型的验证规则。您拥有所有经典 python 类型的等价物。

    arguments 的构造:

        strip_whitespace: bool = False: removes leading and trailing whitespace
        to_lower: bool = False: turns all characters to lowercase
        strict: bool = False: controls type coercion
        min_length: int = None: minimum length of the string
        max_length: int = None: maximum length of the string
        curtail_length: int = None: shrinks the string length to the set value when it is longer than the set value
        regex: str = None: regex to validate the string against
    

    如您所见,这些参数允许您操纵 str 本身,而不是 pydantic 对该字段的行为。

    Field 的用途不同,它是一种自定义字段的方式,所有字段不仅是 str,它还添加了 18 个自定义变量,您可以找到 here

    仅仅是代码风格的问题吗?其中一个优先于另一个吗?

    对于 str 的特定情况,这是代码风格的问题,首选什么并不重要,只有你的用例才重要。

    一般来说,最好不要将不同的语法混在一起,因为你经常需要 Field(),所以你会经常找到它。

    一个典型的用例是在 camelCase 或 PascalCase 中发送 json 对象的 api 响应,您可以使用字段别名来匹配这些对象并在 snake_case 中使用它们的变量。

    exemple:

    class Voice(BaseModel):
        name: str = Field(None, alias='ActorName')
        language_code: str = None
        mood: str = None
    

    在您的第二个问题中,您可以使用字段来实现相同的行为。

    from typing import List
    from pydantic import BaseModel, Field
    
    class Person(BaseModel):
        languages: List[str] = Field(..., min_items=1)
    
    

    如果您想了解有关限制和字段规则执行的更多信息,请查看this

    【讨论】:

    • 谢谢!关于第二个问题,您的解决方案的问题是它要求列表有 1 个项目,这不是我想要的。我需要一个列表,其中的值必须是非空字符串。所以这些是有效的:[]["english", "spanish"];这不是:["german", ""]。为此,除了使用验证器之外,我没有找到任何解决方案来使用Field 实现它。但随后该要求并未自动包含在文档中。
    猜你喜欢
    • 2021-06-29
    • 2021-03-02
    • 2023-01-05
    • 2022-11-22
    • 2022-08-18
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    相关资源
    最近更新 更多