Поля
??? 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'}
- Псевдоним
'username'
используется для создания и проверки экземпляра. - Мы используем
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'}
- Во время проверки используется псевдоним проверки
'username'
. - Имя поля
'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'}
- Имя поля
'name'
используется для проверки. - Для сериализации используется псевдоним сериализации
'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'}}
- Поле
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'
- Это значение по умолчанию.
Дискриминатор¶
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)
- Дополнительную информацию о вспомогательных функциях см. на странице «Модели» .
В следующем примере показано, как использовать аргумент ключевого слова 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
- Это значение по умолчанию.
- Поле
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]
"""
- Поскольку поле
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'}
- Поле
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
本文总阅读量次