Перейти к содержанию

Поля

??? API "Документация по 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)

!!! info Параметры default и default_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 в качестве назначенного значения или с помощью Field.default_factory внутри Annotated . Аргумент Field.default не поддерживается внутри Annotated .

Псевдонимы полей

Для проверки и сериализации вы можете определить псевдоним для поля.

Существует три способа определения псевдонима:

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

Параметр alias используется как для проверки , так и для сериализации. Если вы хотите использовать разные псевдонимы для проверки и сериализации соответственно, вы можете использовать параметры validation_alias serialization_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 для преобразования модели в сериализуемый формат.

Более подробную информацию о model_dump можно найти в справочнике по API.

Обратите внимание, что аргумент ключевого слова 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' .

!!! note «Приоритет и приоритет псевдонимов». Если вы одновременно используете alias вместе с validation_alias или serialization_alias , то validation_alias будет иметь приоритет над alias для проверки, а serialization_alias будет иметь приоритет над alias для сериализации.

If you use an `alias_generator` in the [Model Config][pydantic.config.ConfigDict.alias_generator], 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](../concepts/alias.md#alias-precedence).

??? Совет «Пользователям 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» В сгенерированной схеме 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 :

```py
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)
```

Строковые ограничения

??? API "Документация по 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. Only digits are allowed.

??? info "JSON Schema"
    In the generated JSON schema:

    - `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"
      ]
    }
    ```

## Decimal Constraints

There are fields that can be used to constrain decimals:

* `max_digits`: Maximum number of digits within the `Decimal`. It does not include a zero before the decimal point or
  trailing decimal zeroes.
* `decimal_places`: Maximum number of decimal places allowed. It does not include trailing decimal zeroes.

Here's an example:

```py
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 : должно ли поле быть аргументом только с ключевым словом в конструкторе класса данных.

Вот пример:

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 . Подход Discriminator может быть полезен, когда поля дискриминатора не одинаковы для всех моделей в Union .

В следующем примере показано, как использовать 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 для определения дискриминируемых объединений. Более подробную информацию можно найти в документации по дискриминируемым союзам .

Строгий режим

strict параметр в Field указывает, должно ли поле проверяться в «строгом режиме». В строгом режиме Pydantic выдает ошибку во время проверки вместо принудительного использования данных в поле, где strict=True .

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 можно использовать, чтобы пометить поле как устаревшее. Это приведет к:

  • предупреждение об устаревании среды выполнения, выдаваемое при доступе к полю.
  • "deprecated": true устанавливается в сгенерированной схеме JSON.

Вы можете установить 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'}

deprecated через декоратор warnings.deprecated

!!! note Примечание. Вы можете использовать deprecated декоратор таким образом, только если у вас установлена typing_extensions >= 4.9.0.

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'}

!!! note «Поддержка category и stacklevel ». Текущая реализация этой функции не учитывает аргументы category и stacklevel deprecated декоратора. Это может появиться в будущей версии Pydantic.

!!! предупреждение «Доступ к устаревшему полю в валидаторах» При доступе к устаревшему полю внутри валидатора будет выдано предупреждение об устаревании. Вы можете использовать catch_warnings, чтобы явно игнорировать это:

```py
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.

Декоратор computed_field

??? API "Документация по API" pydantic.fields.computed_field

Декоратор computed_field можно использовать для включения атрибутов property или cached_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

本文总阅读量