简体   繁体   English

Pydantic constr 与 Field args

[英]Pydantic constr vs Field args

I wanted to know what is the difference between:我想知道有什么区别:

from pydantic import BaseModel, Field

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

And:和:

from pydantic import BaseModel, constr

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

Both seem to perform the same validation (even raise the exact same exception info when name is an empty string).两者似乎都执行相同的验证(甚至在name为空字符串时引发完全相同的异常信息)。 Is it just a matter of code style?这只是代码风格的问题吗? Is one of them preferred over the other?其中一个比另一个更受欢迎吗?

Also, if I wanted to include a list of nonempty strings as an attribute, which of these ways do you think would be better?:另外,如果我想包含一个非空字符串列表作为属性,您认为以下哪种方式更好?:

from typing import List
from pydantic import BaseModel, constr

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

Or:或者:

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

EDIT: FWIW, I am using this for a FastAPI app.编辑:FWIW,我将它用于 FastAPI 应用程序。

EDIT2: For my 2nd question, I think the first alternative is better, as it includes the length requirement in the Schema (and so it's in the documentation) EDIT2:对于我的第二个问题,我认为第一个替代方案更好,因为它包括架构中的长度要求(因此它在文档中)

constr and Fields don't serve the same purpose. constr 和 Fields 的用途不同。

constr is a specific type that give validation rules regarding this specific type. constr 是一种特定类型,它提供有关此特定类型的验证规则。 You have equivalent for all classic python types.您拥有所有经典 python 类型的等价物。

arguments of constr: 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

As you can see thoses arguments allow you to manipulate the str itself not the behaviour of pydantic with this field.如您所见,这些 arguments 允许您操纵 str 本身,而不是使用该字段的 pydantic 的行为。

Field doesn't serve the same purpose, it's a way of customizing fields, all fields not only str, it add 18 customization variables that you can find here .字段的用途不同,它是一种自定义字段的方式,所有字段不仅是 str,它还添加了 18 个自定义变量,您可以在此处找到。

Is it just a matter of code style?这只是代码风格的问题吗? Is one of them preferred over the other?其中一个比另一个更受欢迎吗?

for the specific case of str it is a matter of code style and what is preferred doesn't matter, only your usecase does.对于 str 的特定情况,这是代码风格的问题,首选什么并不重要,只有您的用例才重要。

In general it is better to don't mix different syntax toguether and since you often need Field(), you will find it often.一般来说,最好不要将不同的语法混合在一起,因为你经常需要 Field(),你会经常发现它。

A classic use case would be api response that send json object in camelCase or PascalCase, you would use field alias to match thoses object and work with their variables in snake_case. A classic use case would be api response that send json object in camelCase or PascalCase, you would use field alias to match thoses object and work with their variables in snake_case.

exemple : 例子

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

In your second question you could have used field to achive the same behaviour.在您的第二个问题中,您可以使用 field 来实现相同的行为。

from typing import List
from pydantic import BaseModel, Field

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

If you want to learn more about limitation and field rules enforcement check this .如果您想了解有关限制和字段规则执行的更多信息,请查看

This link shows the methods that do and don't work for pydantic and mypy together: https://lyz-code.github.io/blue-book/coding/python/pydantic_types/#using-constrained-strings-in-list-attributes此链接显示了对 pydantic 和 mypy 有效和无效的方法: https://lyz-code.github.io/blue-book/coding/python/pydantic_types/#using-constrained-strings-in-list -属性

The best option for my use case was to make a class that inherited from pydantic.ConstrainedStr as so:我的用例的最佳选择是制作一个继承自pydantic.ConstrainedStr的 class :

import pydantic
from typing import List

...

class Regex(pydantic.ConstrainedStr):
    regex = re.compile("^[0-9a-z_]*$")

class Data(pydantic.BaseModel):
    regex: List[Regex]
    # regex: list[Regex] if you are on 3.9+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM