# Поля сериализатора

## Поля сериализатора

> Каждое поле в классе Form отвечает не только за проверку данных, но и за их "очистку" — приведение их к единообразному формату.
>
> — [Django documentation](https://docs.djangoproject.com/en/stable/ref/forms/api/#django.forms.Form.cleaned_data)

Поля сериализатора выполняют преобразование между примитивными значениями и внутренними типами данных. Они также занимаются проверкой входных значений, а также получением и установкой значений из родительских объектов.

***

**Примечание:** Поля сериализатора объявляются в `fields.py`, но по соглашению вы должны импортировать их с помощью `from rest_framework import serializers` и обращаться к полям как `serializers.<FieldName>`.

***

### Основные аргументы

Каждый конструктор класса поля сериализатора принимает как минимум эти аргументы. Некоторые классы `Field` принимают дополнительные, специфические для поля аргументы, но следующие должны приниматься всегда:

#### `read_only`

Поля, доступные только для чтения, включаются в выходные данные API, но не должны включаться во входные данные при операциях создания или обновления. Любые поля `read_only`, по ошибке включенные во входные данные сериализатора, будут проигнорированы.

Установите значение `True`, чтобы гарантировать, что поле используется при сериализации представления, но не используется при создании или обновлении экземпляра во время десериализации.

По умолчанию `False`.

#### `write_only`

Установите значение `True`, чтобы поле могло использоваться при обновлении или создании экземпляра, но не включалось при сериализации представления.

По умолчанию `False`.

#### `required`

Обычно ошибка возникает, если поле не предоставлено во время десериализации. Установите значение `False`, если это поле не обязательно должно присутствовать при десериализации.

Установка этого значения в `False` также позволяет не выводить атрибут объекта или ключ словаря при сериализации экземпляра. Если ключ не присутствует, он просто не будет включен в выходное представление.

По умолчанию имеет значение `True`. При использовании [Model Serializer](/django-rest-framework-russian-documentation/overview/navigaciya-po-api/serializers.md#modelserializer) значение по умолчанию будет `False`, если вы указали `blank=True` или `default` или `null=True` для вашего поля в вашей `Model`.

#### `default`

Если установлено, это значение по умолчанию, которое будет использоваться для поля, если значение не передано. Если значение не задано, то по умолчанию атрибут вообще не заполняется.

Значение `default` не применяется во время операций частичного обновления. В случае частичного обновления только те поля, которые указаны во входящих данных, получат подтвержденное значение.

Может быть задана как функция или другой вызываемый объект, в этом случае значение будет выполняться каждый раз при его использовании. При вызове оно не получает никаких аргументов. Если вызываемая функция имеет атрибут `requires_context = True`, то поле сериализатора будет передано в качестве аргумента.

Например:

```python
class CurrentUserDefault:
    """
    May be applied as a `default=...` value on a serializer field.
    Returns the current user.
    """
    requires_context = True

    def __call__(self, serializer_field):
        return serializer_field.context['request'].user
```

При сериализации экземпляра будет использоваться значение по умолчанию, если атрибут объекта или ключ словаря не присутствует в экземпляре.

Обратите внимание, что установка значения `default` подразумевает, что поле не является обязательным. Включение обоих именованных аргументов `default` и `required` является недопустимым и приведет к ошибке.

#### `allow_null`

Обычно, если в поле сериализатора передается `None`, возникает ошибка. Установите этот именованный аргумент в `True`, если `None` должно считаться допустимым значением.

Обратите внимание, что без явного указания `default` установка этого аргумента в `True` подразумевает `default` значение `null` для вывода сериализации, но не подразумевает значение по умолчанию для десериализации ввода.

По умолчанию `False`.

#### `source`

Имя атрибута, который будет использоваться для заполнения поля. Может быть методом, который принимает только аргумент `self`, например `URLField(source='get_absolute_url')`, или может использовать точечную нотацию для обхода атрибутов, например `EmailField(source='user.email')`.

При сериализации полей с точечной нотацией может потребоваться предоставить значение `default`, если какой-либо объект отсутствует или пуст при обходе атрибута. Остерегайтесь возможных проблем n+1 при использовании атрибута source, если вы обращаетесь к реляционной модели orm. Например:

```python
class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField(source="user.email")
```

В этом случае объект пользователя должен быть извлечен из базы данных, если он не был предварительно извлечен. Если это нежелательно, убедитесь, что вы используете методы `prefetch_related` и `select_related` соответствующим образом. Более подробную информацию об этих методах можно найти в [документации django](https://docs.djangoproject.com/en/3.1/ref/models/querysets/#django.db.models.query.QuerySet.select_related).

Значение `source='*'` имеет особое значение и используется для указания на то, что в поле должен быть передан весь объект. Это может быть полезно для создания вложенных представлений или для полей, которым требуется доступ к полному объекту для определения выходного представления.

По умолчанию используется имя поля.

#### `validators`

Список функций валидаторов, которые должны быть применены к вводимому полю и которые либо выдают ошибку валидации, либо просто возвращаются. Функции валидатора обычно должны вызывать `serializers.ValidationError`, но встроенный в Django `ValidationError` также поддерживается для совместимости с валидаторами, определенными в кодовой базе Django или в сторонних пакетах Django.

#### `error_messages`

Словарь кодов ошибок и сообщений об ошибках.

#### `label`

Короткая текстовая строка, которая может быть использована в качестве имени поля в полях HTML-формы или других описательных элементах.

#### `help_text`

Текстовая строка, которая может быть использована в качестве описания поля в полях HTML-формы или других описательных элементах.

#### `initial`

Значение, которое должно использоваться для предварительного заполнения значений полей HTML-формы. Вы можете передать ему вызываемый объект, как и в случае с любым обычным полем Django `Field`:

```python
import datetime
from rest_framework import serializers
class ExampleSerializer(serializers.Serializer):
    day = serializers.DateField(initial=datetime.date.today)
```

#### `style`

Словарь пар ключ-значение, которые можно использовать для управления тем, как рендереры должны отображать поле.

Двумя примерами здесь являются `'input_type'` и `'base_template'`:

```python
# Use <input type="password"> for the input.
password = serializers.CharField(
    style={'input_type': 'password'}
)

# Use a radio input instead of a select input.
color_channel = serializers.ChoiceField(
    choices=['red', 'green', 'blue'],
    style={'base_template': 'radio.html'}
)
```

Более подробную информацию можно найти в документации [HTML & Forms](/django-rest-framework-russian-documentation/stati/topics/html-and-forms.md).

***

## Булевы поля

### BooleanField

Булево представление.

При использовании HTML-кодированных форм ввода имейте в виду, что отсутствие значения всегда будет рассматриваться как установка поля в `False`, даже если для него указана опция `default=True`. Это происходит потому, что чекбоксы HTML представляют состояние без флажка в виде отсутствия значение, поэтому DRF воспринимает отсутствие значения как `False`.

Обратите внимание, что в Django 2.1 из `models.BooleanField` был удален именованный аргумент `blank`. До Django 2.1 поля `models.BooleanField` всегда имели значение `blank=True`. Таким образом, начиная с Django 2.1 экземпляры `serializers.BooleanField` по умолчанию будут генерироваться без kwarg `required` (т.е. эквивалентно `required=True`), тогда как в предыдущих версиях Django экземпляры `BooleanField` по умолчанию будут генерироваться с опцией `required=False`. Если вы хотите управлять этим поведением вручную, явно объявите `BooleanField` в классе сериализатора или используйте опцию `extra_kwargs` для установки флага `required`.

Соответствует `django.db.models.fields.BooleanField`.

**Сигнатура:** `BooleanField()`.

***

## Строковые поля

### CharField

Текстовое представление. Опционально проверяет, чтобы текст был короче `max_length` и длиннее `min_length`.

Соответствует `django.db.models.fields.CharField` или `django.db.models.fields.TextField`.

**Сигнатура:** `CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)`.

* `max_length` - Проверяет, что вводимые данные содержат не более этого количества символов.
* `min_length` - Проверяет, что вводимые данные содержат не менее этого количества символов.
* `allow_blank` - Если установлено значение `True`, то пустая строка будет считаться допустимым значением. Если установлено значение `False`, то пустая строка будет считаться недопустимой и вызовет ошибку валидации. По умолчанию `False`.
* `trim_whitespace` - Если установлено значение `True`, то пробельные символы в начале и в конце будут обрезаны. По умолчанию `True`.

Опция `allow_null` также доступна для строковых полей, хотя ее использование не рекомендуется в пользу `allow_blank`. Можно установить и `allow_blank=True`, и `allow_null=True`, но это означает, что для строковых представлений будут допустимы два разных типа пустых значений, что может привести к несоответствию данных и тонким ошибкам в работе приложения.

### EmailField

Текстовое представление, проверяющее, является ли этот текст действительным адресом электронной почты.

Соответствует `django.db.models.fields.EmailField`.

**Сигнатура:** `EmailField(max_length=None, min_length=None, allow_blank=False)`.

### RegexField

Текстовое представление, которое проверяет соответствие заданного значения определенному регулярному выражению.

Соответствует `django.forms.fields.RegexField`.

**Сигнатура:** `RegexField(regex, max_length=None, min_length=None, allow_blank=False)`.

Обязательный аргумент `regex` может быть либо строкой, либо скомпилированным объектом регулярного выражения python.

Для проверки используется `django.core.validators.RegexValidator` от Django.

### SlugField

Поле `RegexField`, которое проверяет вводимые данные на соответствие шаблону `[a-zA-Z0-9_-]+`.

Соответствует `django.db.models.fields.SlugField`.

**Сигнатура:** `SlugField(max_length=50, min_length=None, allow_blank=False)`.

### URLField

Поле `RegexField`, которое проверяет вводимые данные на соответствие шаблону URL. Ожидаются полностью определенные URL вида `http://<host>/<path>`.

Соответствует `django.db.models.fields.URLField`. Для проверки используется `django.core.validators.URLValidator`.

**Сигнатура:** `URLField(max_length=200, min_length=None, allow_blank=False)`.

### UUIDField

Поле, которое гарантирует, что вводимые данные являются правильной строкой UUID. Метод `to_internal_value` возвращает экземпляр `uuid.UUID`. На выходе поле вернет строку в каноническом дефисном формате, например:

```
"de305d54-75b4-431b-adb2-eb6b9e546013"
```

**Сигнатура:** `UUIDField(format='hex_verbose')`.

* `format`: Определяет формат представления значения uuid
  * `'hex_verbose'` - Каноническое шестнадцатеричное представление, включая дефисы: `"5ce0e9a5-5ffa-654b-cee0-1238041fb31a"`.
  * `'hex'` - Компактное шестнадцатеричное представление UUID, не включая дефисы: `"5ce0e9a55ffa654bcee01238041fb31a"`.
  * `'int'` - 128-битное целочисленное представление UUID: `"123456789012312313134124512351145145114"`.
  * `'urn'` - RFC 4122 URN-представление UUID: `'urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a'`. Изменение параметров `формата` влияет только на значения представления. Все форматы принимаются функцией `to_internal_value`.

### FilePathField

Поле, выбор которого ограничен именами файлов в определенном каталоге файловой системы

Соответствует `django.forms.fields.FilePathField`.

**Сигнатура:** `FilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)`.

* `path` - Абсолютный путь файловой системы к директории, из которой это поле FilePathField должно получить свой выбор.
* `match` - Регулярное выражение в виде строки, которое FilePathField будет использовать для фильтрации имен файлов.
* `recursive` - Указывает, должны ли включаться все подкаталоги пути. По умолчанию `False`.
* `allow_files` - Указывает, должны ли включаться файлы в указанном месте. По умолчанию `True`. Либо это, либо `allow_folders` должно быть `True`.
* `allow_folders` - Указывает, должны ли включаться папки в указанном месте. По умолчанию `False`. Либо это, либо `allow_files` должно быть `True`.

### IPAddressField

Поле, гарантирующее, что вводимые данные являются действительной строкой IPv4 или IPv6.

Соответствует `django.forms.fields.IPAddressField` и `django.forms.fields.GenericIPAddressField`.

**Сигнатура**: `IPAddressField(protocol='both', unpack_ipv4=False, **options)`.

* `protocol` Ограничивает допустимые входы указанным протоколом. Принимаемые значения: `'both'` (по умолчанию), `'IPv4'` или `'IPv6'`. Соответствие не зависит от регистра.
* `unpack_ipv4` Распаковывает сопоставленные IPv4-адреса, например `::ffff:192.0.2.1`. Если эта опция включена, то адрес будет распакован в `192.0.2.1`. По умолчанию отключена. Может использоваться только в том случае, если для протокола установлено значение `'both'`.

***

## Числовые поля

### IntegerField

Целочисленное представление.

Соответствует `django.db.models.fields.IntegerField`, `django.db.models.fields.SmallIntegerField`, `django.db.models.fields.PositiveIntegerField` и `django.db.models.fields.PositiveSmallIntegerField`.

**Сигнатура**: `IntegerField(max_value=None, min_value=None)`.

* `max_value` Проверяет, что предоставленное число не больше этого значения.
* `min_value` Проверяет, что предоставленное число не меньше этого значения.

### FloatField

Представление с плавающей точкой.

Соответствует `django.db.models.fields.FloatField`.

**Сигнатура**: `FloatField(max_value=None, min_value=None)`.

* `max_value` Проверяет, что предоставленное число не больше этого значения.
* `min_value` Проверяет, что предоставленное число не меньше этого значения.

### DecimalField

Десятичное представление, представленное в Python экземпляром `Decimal`.

Соответствует `django.db.models.fields.DecimalField`.

**Сигнатура**: `DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)`.

* `max_digits` Максимальное количество цифр, допустимое в числе. Оно должно быть либо `None`, либо целым числом, большим или равным `decimal_places`.
* `decimal_places` Количество десятичных знаков, которые следует хранить в числе.
* `coerce_to_string` Установите значение `True`, если для представления должны быть возвращены строковые значения, или `False`, если должны быть возвращены объекты `Decimal`. По умолчанию имеет то же значение, что и ключ настроек `COERCE_DECIMAL_TO_STRING`, который будет `True`, если его не переопределить. Если сериализатор возвращает `Decimal` объекты, то окончательный формат вывода будет определяться рендерером. Обратите внимание, что установка `localize` заставит значение быть `True`.
* `max_value` Проверяет, что предоставленное число не больше этого значения.
* `min_value` Проверяет, что предоставленное число не меньше этого значения.
* `localize` Установите значение `True`, чтобы включить локализацию ввода и вывода на основе текущей локали. Это также заставит `coerce_to_string` принять значение `True`. По умолчанию установлено значение `False`. Обратите внимание, что форматирование данных будет включено, если вы установили `USE_L10N=True` в вашем файле настроек.
* `rounding` Устанавливает режим округления, используемый при квантовании с заданной точностью. Допустимые значения: [`decimal` module rounding modes](https://docs.python.org/3/library/decimal.html#rounding-modes). По умолчанию `None`.
* `normalize_output` Нормализует десятичное значение при сериализации. При этом удаляются все нули в конце строки и точность значения изменяется до минимально необходимой, чтобы можно было представить значение без потери данных. По умолчанию имеет значение `False`.

**Пример использования**

Для проверки чисел до 999 с разрешением 2 знака после запятой можно использовать:

```python
serializers.DecimalField(max_digits=5, decimal_places=2)
```

А также для проверки чисел вплоть до миллиарда с разрешением 10 знаков после запятой:

```python
serializers.DecimalField(max_digits=19, decimal_places=10)
```

***

## Поля даты и времени

### DateTimeField

Представление даты и времени.

Соответствует `django.db.models.fields.DateTimeField`.

**Сигнатура:** `DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None, default_timezone=None)`.

* `format` - Строка, представляющая формат вывода. Если он не указан, то по умолчанию принимает значение, равное ключу настроек `DATETIME_FORMAT`, который будет `'iso-8601'`, если он не установлен. Установка в строку формата указывает на то, что возвращаемые значения `to_representation` должны быть принудительно приведены к строковому виду. Строки формата описаны ниже. Установка этого значения в `None` указывает, что `to_representation` должен возвращать объекты Python `datetime`. В этом случае кодировка времени будет определяться рендерером.
* `input_formats` - Список строк, представляющих входные форматы, которые могут быть использованы для разбора даты. Если он не указан, будет использоваться настройка `DATETIME_INPUT_FORMATS`, которая по умолчанию принимает значение `['iso-8601']`.
* `default_timezone` - Подкласс `tzinfo` (`zoneinfo` или `pytz`), представляющий часовой пояс. Если он не указан и включен параметр `USE_TZ`, то по умолчанию используется [текущий часовой пояс](https://docs.djangoproject.com/en/stable/topics/i18n/timezones/#default-time-zone-and-current-time-zone). Если `USE_TZ` отключена, то объекты datetime будут наивными.

**Строки формата `DateTimeField`.**

Строки формата могут быть либо [Python strftime formats](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior), которые явно указывают формат, либо специальной строкой `'iso-8601'`, которая указывает на то, что следует использовать значения в стиле [ISO 8601](https://www.w3.org/TR/NOTE-datetime). (Например, `'2013-01-29T12:34:56.000000Z'`)

Если для формата используется значение `None`, то объекты `datetime` будут возвращаться методом `to_representation`, а окончательное представление на выходе будет определяться классом renderer.

**Поля модели `auto_now` и `auto_now_add`.**

При использовании `ModelSerializer` или `HyperlinkedModelSerializer` обратите внимание, что любые поля модели с `auto_now=True` или `auto_now_add=True` будут использовать поля сериализатора, которые по умолчанию имеют значение `read_only=True`.

Если вы хотите переопределить это поведение, вам нужно будет явно объявить `DateTimeField` в сериализаторе. Например:

```python
class CommentSerializer(serializers.ModelSerializer):
    created = serializers.DateTimeField()

    class Meta:
        model = Comment
```

### DateField

Представление даты.

Соответствует `django.db.models.fields.DateField`.

**Сигнатура:** `DateField(format=api_settings.DATE_FORMAT, input_formats=None)`.

* `format` - Строка, представляющая формат вывода. Если он не указан, то по умолчанию принимает значение, равное ключу настроек `DATE_FORMAT`, который будет `'iso-8601'`, если он не установлен. Установка в строку формата указывает на то, что возвращаемые значения `to_representation` должны быть преобразованы в строковый вывод. Строки формата описаны ниже. Установка этого значения в `None` указывает, что `to_representation` должен возвращать объекты Python `date`. В этом случае кодировка даты будет определяться рендерером.
* `input_formats` - Список строк, представляющих входные форматы, которые могут быть использованы для разбора даты. Если он не указан, будет использоваться настройка `DATE_INPUT_FORMATS`, которая по умолчанию принимает значение `['iso-8601']`.

**Строки формата `DateField`.**

Строки формата могут быть либо [Python strftime formats](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior), которые явно указывают формат, либо специальной строкой `'iso-8601'`, которая указывает, что должны использоваться даты в стиле [ISO 8601](https://www.w3.org/TR/NOTE-datetime). (например, `'2013-01-29'`)

### TimeField

Представление времени.

Соответствует `django.db.models.fields.TimeField`.

**Сигнатура:** `TimeField(format=api_settings.TIME_FORMAT, input_formats=None)`.

* `format` - строка, представляющая формат вывода. Если он не указан, то по умолчанию принимает значение, равное ключу настроек `TIME_FORMAT`, который будет `'iso-8601'`, если он не установлен. Установка в строку формата указывает на то, что возвращаемые значения `to_representation` должны быть принудительно выведены в строку. Строки формата описаны ниже. Установка этого значения в `None` указывает, что `to_representation` должен возвращать объекты Python `time`. В этом случае кодировка времени будет определяться рендерером.
* `input_formats` - Список строк, представляющих входные форматы, которые могут быть использованы для разбора даты. Если он не указан, будет использоваться настройка `TIME_INPUT_FORMATS`, которая по умолчанию принимает значение `['iso-8601']`.

**Строки формата `TimeField`.**

Строки формата могут быть либо [Python strftime formats](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior), которые явно указывают формат, либо специальной строкой `'iso-8601'`, которая указывает, что должно использоваться время в стиле [ISO 8601](https://www.w3.org/TR/NOTE-datetime). (например, `'12:34:56.000000'`)

### DurationField

Представление длительности. Соответствует `django.db.models.fields.DurationField`.

В `validated_data` для этих полей будет содержаться экземпляр `datetime.timedelta`. Он представляет собой строку, следующую формату `'[DD] [HH:[MM:]]ss[.uuuuuu]'`.

**Сигнатура:** `DurationField(max_value=None, min_value=None)`.

* `max_value` Проверяет, что предоставленная продолжительность не больше этого значения.
* `min_value` Проверяет, что предоставленная продолжительность не меньше этого значения.

***

## Поля выбора

### ChoiceField

Поле, которое может принимать значение из ограниченного набора вариантов.

Используется `ModelSerializer` для автоматической генерации полей, если соответствующее поле модели содержит аргумент `choices=...`.

**Сигнатура:** `ChoiceField(choices)`.

* `choices` - Список допустимых значений, или список кортежей `(key, display_name)`.
* `allow_blank` - Если установлено значение `True`, то пустая строка будет считаться допустимым значением. Если установлено значение `False`, то пустая строка будет считаться недопустимой и вызовет ошибку валидации. По умолчанию `False`.
* `html_cutoff` - Если установлено, то это будет максимальное количество вариантов, которые будут отображаться в выпадающем списке HTML select. Может использоваться для того, чтобы автоматически генерируемые поля выбора с очень большим количеством возможных вариантов выбора не мешали отрисовке шаблона. По умолчанию `None`.
* `html_cutoff_text` - Если установлено, то будет отображаться текстовый индикатор, если максимальное количество элементов было отсечено в выпадающем списке HTML select. По умолчанию `"More than {count} items..."`.

Оба параметра `allow_blank` и `allow_null` являются допустимыми для `ChoiceField`, хотя настоятельно рекомендуется использовать только один из них, а не оба. `allow_blank` следует предпочесть для текстовых вариантов, а `allow_null` - для числовых или других нетекстовых вариантов.

### MultipleChoiceField

Поле, которое может принимать нулевое, одно или множество значений, выбираемых из ограниченного набора вариантов. Принимает один обязательный аргумент. `to_internal_value` возвращает `set`, содержащий выбранные значения.

**Сигнатура:** `MultipleChoiceField(choices)`.

* `choices` - Список допустимых значений, или список кортежей `(key, display_name)`.
* `allow_blank` - Если установлено значение `True`, то пустая строка будет считаться допустимым значением. Если установлено значение `False`, то пустая строка будет считаться недопустимой и вызовет ошибку валидации. По умолчанию `False`.
* `html_cutoff` - Если установлено, то это будет максимальное количество вариантов, которые будут отображаться в выпадающем списке HTML select. Может использоваться для того, чтобы автоматически генерируемые поля выбора с очень большим количеством возможных вариантов выбора не мешали отрисовке шаблона. По умолчанию `None`.
* `html_cutoff_text` - Если установлено, то будет отображаться текстовый индикатор, если максимальное количество элементов было отсечено в выпадающем списке HTML select. По умолчанию `"More than {count} items..."`.

Как и в случае с `ChoiceField`, оба параметра `allow_blank` и `allow_null` являются допустимыми, хотя настоятельно рекомендуется использовать только один из них, а не оба. `allow_blank` следует предпочесть для текстовых вариантов, а `allow_null` - для числовых или других нетекстовых вариантов.

***

## Поля для загрузки файлов

**Парсеры и загрузка файлов.**

Классы `FileField` и `ImageField` подходят только для использования с `MultiPartParser` или `FileUploadParser`. Большинство парсеров, например, JSON, не поддерживают загрузку файлов. Для работы с загруженными файлами в Django используются штатные [FILE\_UPLOAD\_HANDLERS](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS).

### FileField

Представление файла. Выполняет стандартную для Django проверку `FileField`.

Соответствует `django.forms.fields.FileField`.

**Сигнатура:** `FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)`.

* `max_length` - Указывает максимальную длину имени файла.
* `allow_empty_file` - Указывает, разрешены ли пустые файлы.
* `use_url` - Если установлено значение `True`, то для выходного представления будут использоваться строковые значения URL. Если установлено значение `False`, то для вывода будут использоваться строковые значения имен файлов. По умолчанию принимает значение ключа настроек `UPLOADED_FILES_USE_URL`, которое равно `True`, если не установлено иное.

### ImageField

Представление изображения. Проверяет соответствие содержимого загруженного файла известному формату изображения.

Соответствует `django.forms.fields.ImageField`.

**Сигнатура:** `ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)`.

* `max_length` - Указывает максимальную длину имени файла.
* `allow_empty_file` - Указывает, разрешены ли пустые файлы.
* `use_url` - Если установлено значение `True`, то для выходного представления будут использоваться строковые значения URL. Если установлено значение `False`, то для вывода будут использоваться строковые значения имен файлов. По умолчанию принимает значение ключа настроек `UPLOADED_FILES_USE_URL`, которое равно `True`, если не установлено иное.

Требуется либо пакет `Pillow`, либо пакет `PIL`. Рекомендуется использовать пакет `Pillow`, так как пакет `PIL` больше активно не поддерживается.

***

## Составные поля

### ListField

Класс поля, который проверяет список объектов.

**Сигнатура**: `ListField(child=<A_FIELD_INSTANCE>, allow_empty=True, min_length=None, max_length=None)`.

* `child` - Экземпляр поля, который должен использоваться для проверки объектов в списке. Если этот аргумент не указан, то объекты в списке не будут проверяться.
* `allow_empty` - Указывает, разрешены ли пустые списки.
* `min_length` - Проверяет, что список содержит не менее этого количества элементов.
* `max_length` - Проверяет, что список содержит не более этого количества элементов.

Например, для проверки списка целых чисел вы можете использовать что-то вроде следующего:

```python
scores = serializers.ListField(
   child=serializers.IntegerField(min_value=0, max_value=100)
)
```

Класс `ListField` также поддерживает декларативный стиль, который позволяет писать многократно используемые классы полей списков.

```python
class StringListField(serializers.ListField):
    child = serializers.CharField()
```

Теперь мы можем повторно использовать наш пользовательский класс `StringListField` во всем нашем приложении, без необходимости указывать для него аргумент `child`.

### DictField

Класс поля, который проверяет словарь объектов. Ключи в `DictField` всегда предполагаются как строковые значения.

**Сигнатура**: `DictField(child=<A_FIELD_INSTANCE>, allow_empty=True)`.

* `child` - Экземпляр поля, который должен использоваться для проверки значений в словаре. Если этот аргумент не указан, то значения в отображении не будут проверяться.
* `allow_empty` - Указывает, разрешены ли пустые словари.

Например, чтобы создать поле, которое проверяет сопоставление строк со строками, вы должны написать что-то вроде этого:

```python
document = DictField(child=CharField())
```

Вы также можете использовать декларативный стиль, как в случае с `ListField`. Например:

```python
class DocumentField(DictField):
    child = CharField()
```

### HStoreField

Предварительно настроенное `DictField`, совместимое с `HStoreField` от Django для postgres.

**Сигнатура**: `HStoreField(child=<A_FIELD_INSTANCE>, allow_empty=True)`.

* `child` - экземпляр поля, который используется для проверки значений в словаре. По умолчанию дочернее поле принимает как пустые строки, так и нулевые значения.
* `allow_empty` - Указывает, разрешены ли пустые словари.

Обратите внимание, что дочернее поле **должно** быть экземпляром `CharField`, так как расширение hstore хранит значения в виде строк.

### JSONField

Класс поля, который проверяет, что входящая структура данных состоит из корректных примитивов JSON. В альтернативном двоичном режиме он представляет и проверяет двоичные строки, закодированные в JSON.

**Сигнатура**: `JSONField(binary, encoder)`.

* `binary` - Если установлено значение `True`, то поле будет выводить и проверять строку, закодированную в JSON, а не примитивную структуру данных. По умолчанию `False`.
* `encoder` - Используйте этот JSON-кодер для сериализации входного объекта. По умолчанию `None`.

***

## Разные поля

### ReadOnlyField

Класс поля, который просто возвращает значение поля без изменений.

Это поле используется по умолчанию в `ModelSerializer` при включении имен полей, относящихся к атрибуту, а не к полю модели.

**Сигнатура**: `ReadOnlyField()`.

Например, если бы `has_expired` было свойством модели `Account`, то следующий сериализатор автоматически сгенерировал бы его как `ReadOnlyField`:

```python
class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_name', 'has_expired']
```

### HiddenField

Класс поля, которое не принимает значение на основе пользовательского ввода, а берет его из значения по умолчанию или вызываемого объекта.

**Сигнатура**: `HiddenField()`.

Например, чтобы включить поле, которое всегда предоставляет текущее время как часть проверяемых сериализатором данных, вы должны использовать следующее:

```python
modified = serializers.HiddenField(default=timezone.now)
```

Класс `HiddenField` обычно нужен только в том случае, если у вас есть валидация, которая должна выполняться на основе некоторых предварительно предоставленных значений полей, но вы не хотите открывать все эти поля конечному пользователю.

Другие примеры по `HiddenField` смотрите в документации [validators](/django-rest-framework-russian-documentation/overview/navigaciya-po-api/validators.md).

***

**Примечание:** `HiddenField()` не появляется в сериализаторе `partial=True` (при выполнении запроса `PATCH`). Это поведение может измениться в будущем, следите за обновлениями на [github discussion](https://github.com/encode/django-rest-framework/discussions/8259).

***

### ModelField

Общее поле, которое может быть привязано к любому произвольному полю модели. Класс `ModelField` делегирует задачу сериализации/десериализации связанному с ним полю модели. Это поле можно использовать для создания полей сериализатора для пользовательских полей модели, без необходимости создавать новое пользовательское поле сериализатора.

Это поле используется `ModelSerializer` для соответствия классам полей пользовательской модели.

**Сигнатура:** `ModelField(model_field=<Django ModelField instance>)`.

Класс `ModelField` обычно предназначен для внутреннего использования, но при необходимости может быть использован в вашем API. Чтобы правильно инстанцировать `ModelField`, ему должно быть передано поле, привязанное к инстанцированной модели. Например: `ModelField(model_field=MyModel()._meta.get_field('custom_field'))`.

### SerializerMethodField

Это поле, доступное только для чтения. Оно получает свое значение путем вызова метода класса сериализатора, к которому оно присоединено. Его можно использовать для добавления любых данных в сериализованное представление вашего объекта.

**Сигнатура**: `SerializerMethodField(method_name=None)`.

* `method_name` - Имя метода в сериализаторе, который будет вызван. Если оно не включено, то по умолчанию используется `get_<имя_поля>`.

Метод сериализатора, на который ссылается аргумент `имя_метода`, должен принимать единственный аргумент (в дополнение к `self`), которым является сериализуемый объект. Он должен возвращать все, что вы хотите включить в сериализованное представление объекта. Например:

```python
from django.contrib.auth.models import User
from django.utils.timezone import now
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = '__all__'

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days
```

***

## Пользовательские поля

Если вы хотите создать пользовательское поле, вам нужно создать подкласс `Field`, а затем переопределить один или оба метода `.to_representation()` и `.to_internal_value()`. Эти два метода используются для преобразования между исходным типом данных и примитивным, сериализуемым типом данных. Примитивными типами данных обычно являются число, строка, булево значение, `date`/`time`/`datetime` или `None`. Также это может быть любой список или словарь, содержащий только другие примитивные объекты. Могут поддерживаться и другие типы, в зависимости от используемого рендерера.

Метод `.to_representation()` вызывается для преобразования исходного типа данных в примитивный, сериализуемый тип данных.

Метод `.to_internal_value()` вызывается для восстановления примитивного типа данных в его внутреннее python-представление. Этот метод должен вызвать ошибку `serializers.ValidationError`, если данные недействительны.

### Примеры

#### Базовое пользовательское поле

Давайте рассмотрим пример сериализации класса, представляющего значение цвета RGB:

```python
class Color:
    """
    A color represented in the RGB colorspace.
    """
    def __init__(self, red, green, blue):
        assert(red >= 0 and green >= 0 and blue >= 0)
        assert(red < 256 and green < 256 and blue < 256)
        self.red, self.green, self.blue = red, green, blue

class ColorField(serializers.Field):
    """
    Color objects are serialized into 'rgb(#, #, #)' notation.
    """
    def to_representation(self, value):
        return "rgb(%d, %d, %d)" % (value.red, value.green, value.blue)

    def to_internal_value(self, data):
        data = data.strip('rgb(').rstrip(')')
        red, green, blue = [int(col) for col in data.split(',')]
        return Color(red, green, blue)
```

По умолчанию значения полей рассматриваются как сопоставление с атрибутом объекта. Если вам нужно настроить доступ к значению поля и его установку, вам нужно переопределить `.get_attribute()` и/или `.get_value()`.

В качестве примера создадим поле, которое может быть использовано для представления имени класса сериализуемого объекта:

```python
class ClassNameField(serializers.Field):
    def get_attribute(self, instance):
        # We pass the object instance onto `to_representation`,
        # not just the field attribute.
        return instance

    def to_representation(self, value):
        """
        Serialize the value's class name.
        """
        return value.__class__.__name__
```

#### Вызов ошибок проверки

Наш класс `ColorField`, описанный выше, в настоящее время не выполняет никакой проверки данных. Чтобы указать на недопустимые данные, мы должны вызвать ошибку `serializers.ValidationError`, как показано ниже:

```python
def to_internal_value(self, data):
    if not isinstance(data, str):
        msg = 'Incorrect type. Expected a string, but got %s'
        raise ValidationError(msg % type(data).__name__)

    if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
        raise ValidationError('Incorrect format. Expected `rgb(#,#,#)`.')

    data = data.strip('rgb(').rstrip(')')
    red, green, blue = [int(col) for col in data.split(',')]

    if any([col > 255 or col < 0 for col in (red, green, blue)]):
        raise ValidationError('Value out of range. Must be between 0 and 255.')

    return Color(red, green, blue)
```

Метод `.fail()` - это ярлык для вызова `ValidationError`, который принимает строку сообщения из словаря `error_messages`. Например:

```python
default_error_messages = {
    'incorrect_type': 'Incorrect type. Expected a string, but got {input_type}',
    'incorrect_format': 'Incorrect format. Expected `rgb(#,#,#)`.',
    'out_of_range': 'Value out of range. Must be between 0 and 255.'
}

def to_internal_value(self, data):
    if not isinstance(data, str):
        self.fail('incorrect_type', input_type=type(data).__name__)

    if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
        self.fail('incorrect_format')

    data = data.strip('rgb(').rstrip(')')
    red, green, blue = [int(col) for col in data.split(',')]

    if any([col > 255 or col < 0 for col in (red, green, blue)]):
        self.fail('out_of_range')

    return Color(red, green, blue)
```

Этот стиль делает сообщения об ошибках более чистыми и отделенными от кода, поэтому его следует предпочесть.

#### Использование `source='*'`

Здесь мы рассмотрим пример *плоской* модели `DataPoint` с атрибутами `x_coordinate` и `y_coordinate`.

```python
class DataPoint(models.Model):
    label = models.CharField(max_length=50)
    x_coordinate = models.SmallIntegerField()
    y_coordinate = models.SmallIntegerField()
```

Используя пользовательское поле и `source='*'`, мы можем предоставить вложенное представление пары координат:

```python
class CoordinateField(serializers.Field):

    def to_representation(self, value):
        ret = {
            "x": value.x_coordinate,
            "y": value.y_coordinate
        }
        return ret

    def to_internal_value(self, data):
        ret = {
            "x_coordinate": data["x"],
            "y_coordinate": data["y"],
        }
        return ret

class DataPointSerializer(serializers.ModelSerializer):
    coordinates = CoordinateField(source='*')

    class Meta:
        model = DataPoint
        fields = ['label', 'coordinates']
```

Обратите внимание, что в этом примере не предусмотрена валидация. Отчасти по этой причине в реальном проекте вложенность координат может быть лучше обработана с помощью вложенного сериализатора используя `source='*'`, с двумя экземплярами `IntegerField`, каждый из которых имеет свой собственный `source` указывающий на соответствующее поле.

Ключевыми моментами из этого примера являются следующие:

* `to_representation` передается весь объект `DataPoint`, который должен быть отображен в нужный вывод.

  ```python
  >>> instance = DataPoint(label='Example', x_coordinate=1, y_coordinate=2)
  >>> out_serializer = DataPointSerializer(instance)
  >>> out_serializer.data
  ReturnDict([('label', 'Example'), ('coordinates', {'x': 1, 'y': 2})])
  ```
* Если только наше поле не будет доступно только для чтения, `to_internal_value` должно возвращать дикту, подходящую для обновления целевого объекта. При использовании `source='*'`, возврат из `to_internal_value` будет обновлять корневой словарь данных, а не один ключ.

  ```python
  >>> data = {
  ...     "label": "Second Example",
  ...     "coordinates": {
  ...         "x": 3,
  ...         "y": 4,
  ...     }
  ... }
  >>> in_serializer = DataPointSerializer(data=data)
  >>> in_serializer.is_valid()
  True
  >>> in_serializer.validated_data
  OrderedDict([('label', 'Second Example'),
              ('y_coordinate', 4),
              ('x_coordinate', 3)])
  ```

Для полноты картины повторим то же самое, но с использованием вложенного сериализатора, предложенного выше:

```python
class NestedCoordinateSerializer(serializers.Serializer):
    x = serializers.IntegerField(source='x_coordinate')
    y = serializers.IntegerField(source='y_coordinate')

class DataPointSerializer(serializers.ModelSerializer):
    coordinates = NestedCoordinateSerializer(source='*')

    class Meta:
        model = DataPoint
        fields = ['label', 'coordinates']
```

Здесь отображение между парами атрибутов цели и источника (`x` и `x_coordinate`, `y` и `y_coordinate`) обрабатывается в объявлениях `IntegerField`. Это наш `NestedCoordinateSerializer`, который принимает `source='*'`.

Наш новый `DataPointSerializer` демонстрирует то же поведение, что и подход с пользовательскими полями.

Сериализация:

```python
>>> out_serializer = DataPointSerializer(instance)
>>> out_serializer.data
ReturnDict([('label', 'testing'),
            ('coordinates', OrderedDict([('x', 1), ('y', 2)]))])
```

Десериализация:

```python
>>> in_serializer = DataPointSerializer(data=data)
>>> in_serializer.is_valid()
True
>>> in_serializer.validated_data
OrderedDict([('label', 'still testing'),
             ('x_coordinate', 3),
             ('y_coordinate', 4)])
```

Но мы также получаем встроенную валидацию бесплатно:

```python
>>> invalid_data = {
...     "label": "still testing",
...     "coordinates": {
...         "x": 'a',
...         "y": 'b',
...     }
... }
>>> invalid_serializer = DataPointSerializer(data=invalid_data)
>>> invalid_serializer.is_valid()
False
>>> invalid_serializer.errors
ReturnDict([('coordinates',
             {'x': ['A valid integer is required.'],
              'y': ['A valid integer is required.']})])
```

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

## Пакеты сторонних производителей

Также доступны следующие пакеты сторонних производителей.

### Составные поля DRF

Пакет [drf-compound-fields](https://drf-compound-fields.readthedocs.io) предоставляет "составные" поля сериализатора, такие как списки простых значений, которые могут быть описаны другими полями, а не сериализаторами с опцией `many=True`. Также предоставляются поля для типизированных словарей и значений, которые могут быть либо определенным типом, либо списком элементов этого типа.

### Дополнительные поля DRF

Пакет [drf-extra-fields](https://github.com/Hipo/drf-extra-fields) предоставляет дополнительные поля сериализатора для DRF, включая классы `Base64ImageField` и `PointField`.

### djangorestframework-recursive

Пакет [djangorestframework-recursive](https://github.com/heywbj/django-rest-framework-recursive) предоставляет `RecursiveField` для сериализации и десериализации рекурсивных структур.

### django-rest-framework-gis

Пакет [django-rest-framework-gis](https://github.com/djangonauts/django-rest-framework-gis) предоставляет географические дополнения для DRF, такие как поле `GeometryField` и сериализатор GeoJSON.

### django-rest-framework-hstore

Пакет [django-rest-framework-hstore](https://github.com/djangonauts/django-rest-framework-hstore) предоставляет `HStoreField` для поддержки поля модели [django-hstore](https://github.com/djangonauts/django-hstore) `DictionaryField`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ilyachch.gitbook.io/django-rest-framework-russian-documentation/overview/navigaciya-po-api/fields.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
