跳转至

字段

API 文档

pydantic.fields.Field

Field 函数用于自定义和向模型字段添加元数据。

默认值

default 参数用于为字段定义默认值。

from pydantic import BaseModel, Field


class User(BaseModel):
    name: str = Field(default='John Doe')


user = User()
print(user)
#> name='John Doe'

你还可以使用 default_factory 来定义一个可调用的函数,该函数将被调用以生成默认值。

from uuid import uuid4

from pydantic import BaseModel, Field


class User(BaseModel):
    id: str = Field(default_factory=lambda: uuid4().hex)

信息

defaultdefault_factory 参数相互排斥。

注意

如果使用 typing.Optional ,并不意味着该字段有默认值 None

使用 Annotated

Field 函数也可以与 Annotated 一起使用。

from uuid import uuid4

from typing_extensions import Annotated

from pydantic import BaseModel, Field


class User(BaseModel):
    id: Annotated[str, Field(default_factory=lambda: uuid4().hex)]

注意

默认值可以在 Annotated 外部设置为赋值,也可以在 Annotated 内部使用 Field.default_factory 设置。 Annotated 内部不支持 Field.default 参数。

字段别名

对于验证和序列化,可以为字段定义别名。

有三种定义别名的方法:

  • Field(..., alias='foo')
  • Field(..., validation_alias='foo')
  • Field(..., serialization_alias='foo')

alias 参数既用于验证,也用于序列化。如果希望分别为验证和序列化使用不同的别名,可以使用 validation_aliasserialization_alias 参数,它们将仅在各自的用例中应用。

以下是使用 alias 参数的示例:

from pydantic import BaseModel, Field


class User(BaseModel):
    name: str = Field(..., alias='username')


user = User(username='johndoe')  # (1)!
print(user)
#> name='johndoe'
print(user.model_dump(by_alias=True))  # (2)!
#> {'username': 'johndoe'}
  1. 别名 'username' 用于实例创建和验证。

  2. 我们正在使用 `model_dump` 将模型转换为可序列化的格式。
    

    你可以在 API 参考中查看有关 model_dump 的更多详细信息。

    请注意, by_alias 关键字参数默认值为 False ,必须显式指定才能使用字段(序列化)别名转储模型。

    by_alias=True 时,序列化期间也使用别名 'username'

如果你只想将别名用于验证,可以使用 validation_alias 参数:

from pydantic import BaseModel, Field


class User(BaseModel):
    name: str = Field(..., validation_alias='username')


user = User(username='johndoe')  # (1)!
print(user)
#> name='johndoe'
print(user.model_dump(by_alias=True))  # (2)!
#> {'name': 'johndoe'}
  1. 验证别名 'username' 在验证期间使用。

  2. 序列化期间使用了字段名 'name'

如果你只想为序列化定义别名,可以使用 serialization_alias 参数:

from pydantic import BaseModel, Field


class User(BaseModel):
    name: str = Field(..., serialization_alias='username')


user = User(name='johndoe')  # (1)!
print(user)
#> name='johndoe'
print(user.model_dump(by_alias=True))  # (2)!
#> {'username': 'johndoe'}
  1. 该字段名 'name' 用于验证。

  2. 使用序列化别名 'username' 进行序列化。

注意

“别名优先级和优先级” 如果同时使用 aliasvalidation_aliasserialization_alias ,则 validation_alias 在验证方面将优先于 aliasserialization_alias 在序列化方面将优先于 alias

If you use an alias_generator in the Model Config, you can control the order of precedence for specified field vs generated aliases via the alias_priority setting. You can read more about alias precedence here.

提示“VSCode 和 Pyright 用户”:在 VSCode 中,如果使用 Pylance 扩展,使用字段别名实例化模型时不会看到警告:

```py
from pydantic import BaseModel, Field


class User(BaseModel):
    name: str = Field(..., alias='username')


user = User(username='johndoe')  # (1)!
```

1. VSCode will NOT show a warning here.

When the `'alias'` keyword argument is specified, even if you set `populate_by_name` to `True` in the
[Model Config][pydantic.config.ConfigDict.populate_by_name], VSCode will show a warning when instantiating
a model using the field name (though it will work at runtime) — in this case, `'name'`:

```py
from pydantic import BaseModel, ConfigDict, Field


class User(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    name: str = Field(..., alias='username')


user = User(name='johndoe')  # (1)!
```

1. VSCode will show a warning here.

To "trick" VSCode into preferring the field name, you can use the `str` function to wrap the alias value.
With this approach, though, a warning is shown when instantiating a model using the alias for the field:

```py
from pydantic import BaseModel, ConfigDict, Field


class User(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    name: str = Field(..., alias=str('username'))  # noqa: UP018


user = User(name='johndoe')  # (1)!
user = User(username='johndoe')  # (2)!
```

1. Now VSCode will NOT show a warning
2. VSCode will show a warning here, though

This is discussed in more detail in [this issue](https://github.com/pydantic/pydantic/issues/5893).

### Validation Alias

Even though Pydantic treats `alias` and `validation_alias` the same when creating model instances, VSCode will not
use the `validation_alias` in the class initializer signature. If you want VSCode to use the `validation_alias`
in the class initializer, you can instead specify both an `alias` and `serialization_alias`, as the
`serialization_alias` will override the `alias` during serialization:

```py
from pydantic import BaseModel, Field


class MyModel(BaseModel):
    my_field: int = Field(..., validation_alias='myValidationAlias')
```
with:
```py
from pydantic import BaseModel, Field


class MyModel(BaseModel):
    my_field: int = Field(
        ...,
        alias='myValidationAlias',
        serialization_alias='my_serialization_alias',
    )


m = MyModel(myValidationAlias=1)
print(m.model_dump(by_alias=True))
#> {'my_serialization_alias': 1}
```

All of the above will likely also apply to other tools that respect the
[`@typing.dataclass_transform`](https://docs.python.org/3/library/typing.html#typing.dataclass_transform)
decorator, such as Pyright.

有关别名用法的更多信息,请参阅别名概念页面。

数字约束

有一些关键字参数可用于限制数值:

  • gt - 大于
  • lt - 小于
  • ge - 大于或等于

  • le - 小于或等于

  • multiple_of - 给定数字的倍数

  • allow_inf_nan - 允许 'inf''-inf''nan'

以下是一个示例: 翻译文本:

from pydantic import BaseModel, Field


class Foo(BaseModel):
    positive: int = Field(gt=0)
    non_negative: int = Field(ge=0)
    negative: int = Field(lt=0)
    non_positive: int = Field(le=0)
    even: int = Field(multiple_of=2)
    love_for_pydantic: float = Field(allow_inf_nan=True)


foo = Foo(
    positive=1,
    non_negative=0,
    negative=-1,
    non_positive=0,
    even=2,
    love_for_pydantic=float('inf'),
)
print(foo)
"""
positive=1 non_negative=0 negative=-1 non_positive=0 even=2 love_for_pydantic=inf
"""

在生成的 JSON 模式中:

- `gt` and `lt` constraints will be translated to `exclusiveMinimum` and `exclusiveMaximum`.
- `ge` and `le` constraints will be translated to `minimum` and `maximum`.
- `multiple_of` constraint will be translated to `multipleOf`.

The above snippet will generate the following JSON Schema:

```json
{
  "title": "Foo",
  "type": "object",
  "properties": {
    "positive": {
      "title": "Positive",
      "type": "integer",
      "exclusiveMinimum": 0
    },
    "non_negative": {
      "title": "Non Negative",
      "type": "integer",
      "minimum": 0
    },
    "negative": {
      "title": "Negative",
      "type": "integer",
      "exclusiveMaximum": 0
    },
    "non_positive": {
      "title": "Non Positive",
      "type": "integer",
      "maximum": 0
    },
    "even": {
      "title": "Even",
      "type": "integer",
      "multipleOf": 2
    },
    "love_for_pydantic": {
      "title": "Love For Pydantic",
      "type": "number"
    }
  },
  "required": [
    "positive",
    "non_negative",
    "negative",
    "non_positive",
    "even",
    "love_for_pydantic"
  ]
}
```

See the [JSON Schema Draft 2020-12] for more details.

警告

"复合类型的约束" 如果你使用具有复合类型的字段约束,在某些情况下可能会发生错误。为避免潜在问题,你可以使用 Annotated

from typing import Optional

from typing_extensions import Annotated

from pydantic import BaseModel, Field


class Foo(BaseModel):
    positive: Optional[Annotated[int, Field(gt=0)]]
    # Can error in some cases, not recommended:
    non_negative: Optional[int] = Field(ge=0)

String Constraints

字符串约束

API 文档

pydantic.types.StringConstraints

有可以用于约束字符串的字段:

  • min_length :字符串的最小长度。

  • max_length :字符串的最大长度。

  • pattern :字符串必须匹配的正则表达式。

以下是一个示例: 翻译文本:

from pydantic import BaseModel, Field


class Foo(BaseModel):
    short: str = Field(min_length=3)
    long: str = Field(max_length=10)
    regex: str = Field(pattern=r'^\d*$')  # (1)!


foo = Foo(short='foo', long='foobarbaz', regex='123')
print(foo)
#> short='foo' long='foobarbaz' regex='123'
  1. 仅允许数字。

在生成的 JSON 模式中:

- `min_length` constraint will be translated to `minLength`.
- `max_length` constraint will be translated to `maxLength`.
- `pattern` constraint will be translated to `pattern`.

The above snippet will generate the following JSON Schema:

```json
{
  "title": "Foo",
  "type": "object",
  "properties": {
    "short": {
      "title": "Short",
      "type": "string",
      "minLength": 3
    },
    "long": {
      "title": "Long",
      "type": "string",
      "maxLength": 10
    },
    "regex": {
      "title": "Regex",
      "type": "string",
      "pattern": "^\\d*$"
    }
  },
  "required": [
    "short",
    "long",
    "regex"
  ]
}
```

小数约束

有可以用于限制小数位数的字段:

  • max_digitsDecimal 内的最大数字位数。它不包括小数点前的零或尾随的小数零。

  • decimal_places :允许的最大小数位数。不包括尾随的小数零。

以下是一个示例: 翻译文本:

from decimal import Decimal

from pydantic import BaseModel, Field


class Foo(BaseModel):
    precise: Decimal = Field(max_digits=5, decimal_places=2)


foo = Foo(precise=Decimal('123.45'))
print(foo)
#> precise=Decimal('123.45')

数据类约束

有一些字段可用于约束数据类:

  • init :该字段是否应包含在数据类的 __init__ 中。

  • init_var :该字段是否应在数据类中被视为仅初始化字段。

  • kw_only :该字段是否应在 dataclass 构造函数中成为仅限关键字的参数。

以下是一个示例: 翻译文本:

from pydantic import BaseModel, Field
from pydantic.dataclasses import dataclass


@dataclass
class Foo:
    bar: str
    baz: str = Field(init_var=True)
    qux: str = Field(kw_only=True)


class Model(BaseModel):
    foo: Foo


model = Model(foo=Foo('bar', baz='baz', qux='qux'))
print(model.model_dump())  # (1)!
#> {'foo': {'bar': 'bar', 'qux': 'qux'}}
  1. 由于 baz 字段是只初始化的字段,因此它未包含在 model_dump() 输出中。

验证默认值

参数 validate_default 可用于控制字段的默认值是否应进行验证。

默认情况下,该字段的默认值不进行验证。

from pydantic import BaseModel, Field, ValidationError


class User(BaseModel):
    age: int = Field(default='twelve', validate_default=True)


try:
    user = User()
except ValidationError as e:
    print(e)
    """
    1 validation error for User
    age
      Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='twelve', input_type=str]
    """

字段表示

参数 repr 可用于控制该字段是否应包含在模型的字符串表示中。

from pydantic import BaseModel, Field


class User(BaseModel):
    name: str = Field(repr=True)  # (1)!
    age: int = Field(repr=False)


user = User(name='John', age=42)
print(user)
#> name='John'
  1. 这是默认值。

鉴别器

参数 discriminator 可用于控制在联合中用于区分不同模型的字段。它可以是字段的名称或 Discriminator 实例。当 Union 中的所有模型的判别字段不完全相同时, Discriminator 方法可能很有用。

以下示例展示了如何使用字段名使用 discriminator

from typing import Literal, Union

from pydantic import BaseModel, Field


class Cat(BaseModel):
    pet_type: Literal['cat']
    age: int


class Dog(BaseModel):
    pet_type: Literal['dog']
    age: int


class Model(BaseModel):
    pet: Union[Cat, Dog] = Field(discriminator='pet_type')


print(Model.model_validate({'pet': {'pet_type': 'cat', 'age': 12}}))  # (1)!
#> pet=Cat(pet_type='cat', age=12)
  1. 查看更多关于模型页面中的辅助功能。

以下示例展示了如何使用 discriminator 关键字参数与 Discriminator 实例:

from typing import Literal, Union

from typing_extensions import Annotated

from pydantic import BaseModel, Discriminator, Field, Tag


class Cat(BaseModel):
    pet_type: Literal['cat']
    age: int


class Dog(BaseModel):
    pet_kind: Literal['dog']
    age: int


def pet_discriminator(v):
    if isinstance(v, dict):
        return v.get('pet_type', v.get('pet_kind'))
    return getattr(v, 'pet_type', getattr(v, 'pet_kind', None))


class Model(BaseModel):
    pet: Union[Annotated[Cat, Tag('cat')], Annotated[Dog, Tag('dog')]] = Field(
        discriminator=Discriminator(pet_discriminator)
    )


print(repr(Model.model_validate({'pet': {'pet_type': 'cat', 'age': 12}})))
#> Model(pet=Cat(pet_type='cat', age=12))

print(repr(Model.model_validate({'pet': {'pet_kind': 'dog', 'age': 12}})))
#> Model(pet=Dog(pet_kind='dog', age=12))

你还可以利用 Annotated 来定义你的 discriminated unions。更多详细信息请参考 discriminated unions 文档。

严格模式

@pydantic.fields.Field 的 [ Field ] 上的 strict 参数指定了该字段是否应在“严格模式”下进行验证。在严格模式下,Pydantic 在验证期间会引发错误,而不是在字段上强制转换数据。

from pydantic import BaseModel, Field


class User(BaseModel):
    name: str = Field(strict=True)  # (1)!
    age: int = Field(strict=False)


user = User(name='John', age='42')  # (2)!
print(user)
#> name='John' age=42
  1. 这是默认值。

  2. 在严格模式下, age 字段未被验证。因此,可以将其赋值为字符串。

请参阅严格模式以获取更多详细信息。

有关 Pydantic 在严格和宽松模式下如何转换数据的更多详细信息,请参见转换表。

不变性

参数 frozen 用于模拟冻结的数据类行为。它用于防止在创建模型后为字段分配新值(不可变)。

请参阅冻结的数据类文档以获取更多详细信息。

from pydantic import BaseModel, Field, ValidationError


class User(BaseModel):
    name: str = Field(frozen=True)
    age: int


user = User(name='John', age=42)

try:
    user.name = 'Jane'  # (1)!
except ValidationError as e:
    print(e)
    """
    1 validation error for User
    name
      Field is frozen [type=frozen_field, input_value='Jane', input_type=str]
    """
  1. 由于 name 字段被冻结,不允许赋值。

排除

exclude 参数可用于控制导出模型时应从模型中排除哪些字段。

请参见以下示例:

from pydantic import BaseModel, Field


class User(BaseModel):
    name: str
    age: int = Field(exclude=True)


user = User(name='John', age=42)
print(user.model_dump())  # (1)!
#> {'name': 'John'}
  1. 由于被排除在外, age 字段未包含在 model_dump() 输出中。

请参阅序列化部分以获取更多详细信息。

已弃用的字段

deprecated 参数可用于将字段标记为已弃用。这样做会导致:

  • 访问该字段时发出的运行时弃用警告。

  • 在生成的 JSON 模式中设置 "deprecated": true

你可以将 deprecated 参数设置为以下之一:

  • 一个字符串,将用作弃用消息。

  • warnings.deprecated 装饰器(或 typing_extensions 的回溯)的一个实例。

  • 一个布尔值,用于将该字段标记为已弃用,并使用默认的 'deprecated' 弃用消息。

deprecated 作为一个字符串

from typing_extensions import Annotated

from pydantic import BaseModel, Field


class Model(BaseModel):
    deprecated_field: Annotated[int, Field(deprecated='This is deprecated')]


print(Model.model_json_schema()['properties']['deprecated_field'])
#> {'deprecated': True, 'title': 'Deprecated Field', 'type': 'integer'}

通过 warnings.deprecated 修饰器的 deprecated

注意

如果安装了 typing_extensions >= 4.9.0,则只能以这种方式使用 deprecated 修饰符。

import importlib.metadata

from packaging.version import Version from typing_extensions import Annotated, deprecated

from pydantic import BaseModel, Field

if Version(importlib.metadata.version('typing_extensions')) >= Version('4.9'):

class Model(BaseModel):
    deprecated_field: Annotated[int, deprecated('This is deprecated')]

    # Or explicitly using `Field`:
    alt_form: Annotated[
        int, Field(deprecated=deprecated('This is deprecated'))
    ]

deprecated 为布尔值

from typing_extensions import Annotated

from pydantic import BaseModel, Field


class Model(BaseModel):
    deprecated_field: Annotated[int, Field(deprecated=True)]


print(Model.model_json_schema()['properties']['deprecated_field'])
#> {'deprecated': True, 'title': 'Deprecated Field', 'type': 'integer'}

注意

“支持 categorystacklevel ” 目前此功能的实现没有考虑到 deprecated 装饰器的 categorystacklevel 参数。这可能会在 Pydantic 的未来版本中实现。

警告

"访问验证器中的已弃用字段" 在验证器内部访问已弃用的字段时,将发出弃用警告。您可以使用 catch_warnings 来显式忽略它:

import warnings

from typing_extensions import Self

from pydantic import BaseModel, Field, model_validator


class Model(BaseModel):
    deprecated_field: int = Field(deprecated='This is deprecated')

    @model_validator(mode='after')
    def validate_model(self) -> Self:
        with warnings.catch_warnings():
            warnings.simplefilter('ignore', DeprecationWarning)
            self.deprecated_field = self.deprecated_field * 2

自定义 JSON 模式

一些字段参数专门用于自定义生成的 JSON 模式。这些参数是:

  • title
  • description
  • examples
  • json_schema_extra

有关 JSON 模式定制/修改的更多信息,请在 JSON 模式文档的“自定义 JSON 模式”部分中查看字段。

The computed_field decorator

computed_field 修饰符

API 文档

pydantic.fields.computed_field

computed_field 装饰器可用于在序列化模型或数据类时包含 propertycached_property 属性。这对于从其他字段计算得出的字段或计算成本高(因此被缓存)的字段很有用。

以下是一个示例: 翻译文本:

from pydantic import BaseModel, computed_field


class Box(BaseModel):
    width: float
    height: float
    depth: float

    @computed_field
    def volume(self) -> float:
        return self.width * self.height * self.depth


b = Box(width=1, height=2, depth=3)
print(b.model_dump())
#> {'width': 1.0, 'height': 2.0, 'depth': 3.0, 'volume': 6.0}

与常规字段一样,可以将计算字段标记为已弃用:

from typing_extensions import deprecated

from pydantic import BaseModel, computed_field


class Box(BaseModel):
    width: float
    height: float
    depth: float

    @computed_field
    @deprecated("'volume' is deprecated")
    def volume(self) -> float:
        return self.width * self.height * self.depth

本文总阅读量