Сериализаторы
Last updated
Was this helpful?
Last updated
Was this helpful?
источник:
serializers.py
Расширение полезности сериализаторов - это то, чем мы хотели бы заняться. Однако это не тривиальная проблема, и она потребует серьезной работы над дизайном.
— Russell Keith-Magee,
Сериализаторы позволяют преобразовывать сложные данные, такие как наборы запросов и экземпляры моделей, в собственные типы данных Python, которые затем могут быть легко преобразованы в JSON
, XML
или другие типы содержимого. Сериализаторы также обеспечивают десериализацию, позволяя преобразовывать разобранные данные обратно в сложные типы после предварительной проверки входящих данных.
Сериализаторы в DRF работают очень похоже на классы Django Form
и ModelForm
. Мы предоставляем класс Serializer
, который дает вам мощный, универсальный способ управления выводом ваших ответов, а также класс ModelSerializer
, который предоставляет полезный ярлык для создания сериализаторов, работающих с экземплярами моделей и наборами запросов.
Давайте начнем с создания простого объекта, который мы можем использовать для примера:
Мы объявим сериализатор, который мы можем использовать для сериализации и десериализации данных, соответствующих объектам Comment
.
Объявление сериализатора очень похоже на объявление формы:
Теперь мы можем использовать CommentSerializer
для сериализации комментария или списка комментариев. Опять же, использование класса Serializer
очень похоже на использование класса Form
.
На данном этапе мы перевели экземпляр модели в собственные типы данных Python. Чтобы завершить процесс сериализации, мы преобразуем данные в json
.
Десериализация аналогична. Сначала мы разбираем поток на собственные типы данных Python...
затем мы восстанавливаем эти родные типы данных в словарь проверенных данных.
Если мы хотим иметь возможность возвращать полные экземпляры объектов на основе проверенных данных, нам необходимо реализовать один или оба метода .create()
и .update()
. Например:
Если ваши экземпляры объектов соответствуют моделям Django, вы также захотите убедиться, что эти методы сохраняют объект в базе данных. Например, если Comment
является моделью Django, методы могут выглядеть следующим образом:
Теперь при десериализации данных мы можем вызвать .save()
, чтобы вернуть экземпляр объекта, основанный на проверенных данных.
Вызов .save()
либо создаст новый экземпляр, либо обновит существующий, в зависимости от того, был ли передан существующий экземпляр при инстанцировании класса сериализатора:
Методы .create()
и .update()
являются необязательными. Вы можете реализовать либо ни один из них, либо один, либо оба, в зависимости от условий использования вашего класса сериализатора.
Передача дополнительных атрибутов в .save()
.
Иногда вы хотите, чтобы код представления мог вводить дополнительные данные в момент сохранения экземпляра. Эти дополнительные данные могут включать информацию о текущем пользователе, текущем времени или что-нибудь еще, что не является частью данных запроса.
Вы можете сделать это, включив дополнительные именованные аргументы при вызове .save()
. Например:
Любые дополнительные именованные аргументы будут включены в аргумент validated_data
при вызове .create()
или .update()
.
Переопределение .save()
напрямую.
В некоторых случаях имена методов .create()
и .update()
могут не иметь смысла. Например, в контактной форме мы можем не создавать новые экземпляры, а отправлять электронное письмо или другое сообщение.
В этих случаях вы можете вместо этого переопределить .save()
напрямую, как более читабельный и осмысленный.
Например:
Обратите внимание, что в приведенном выше случае нам приходится напрямую обращаться к свойству сериализатора .validated_data
.
При десериализации данных всегда нужно вызывать is_valid()
прежде, чем пытаться получить доступ к проверенным данным или сохранить экземпляр объекта. Если возникнут ошибки валидации, свойство .errors
будет содержать словарь, представляющий сообщения об ошибках. Например:
Каждый ключ в словаре будет именем поля, а значения будут списками строк любых сообщений об ошибках, соответствующих этому полю. Также может присутствовать ключ non_field_errors
, в котором будут перечислены все общие ошибки валидации. Имя ключа non_field_errors
можно настроить с помощью параметра DRF NON_FIELD_ERRORS_KEY
.
При десериализации списка элементов ошибки будут возвращены в виде списка словарей, представляющих каждый из десериализованных элементов.
Возбуждение исключения при недопустимых данных
Метод .is_valid()
принимает необязательный флаг raise_exception
, который заставит его поднять исключение serializers.ValidationError
, если есть ошибки валидации.
Эти исключения автоматически обрабатываются обработчиком исключений по умолчанию, который предоставляет DRF, и по умолчанию будут возвращать ответы HTTP 400 Bad Request
.
Валидация на уровне поля
Вы можете задать пользовательскую валидацию на уровне полей, добавив методы .validate_<имя_поля>
в подкласс Serializer
. Они аналогичны методам .clean_<имя_поля>
в формах Django.
Эти методы принимают единственный аргумент, который является значением поля, требующего проверки.
Ваши методы validate_<имя_поля>
должны возвращать проверенное значение или вызывать serializers.ValidationError
. Например:
Примечание: Если ваше <имя_поля>
объявлено в вашем сериализаторе с параметром required=False
, то этот шаг валидации не будет выполняться, если поле не включено.
Валидация на уровне объекта
Чтобы выполнить любую другую проверку, требующую доступа к нескольким полям, добавьте метод .validate()
к вашему подклассу Serializer
. Этот метод принимает единственный аргумент, который является словарем значений полей. При необходимости он должен вызывать `serializers.ValidationError, или просто возвращать проверенные значения. Например:
Валидаторы
Отдельные поля сериализатора могут включать валидаторы, например, путем объявления их в экземпляре поля:
Классы сериализаторов могут также включать многократно используемые валидаторы, которые применяются к полному набору данных поля. Эти валидаторы включаются путем объявления их во внутреннем классе Meta
, например, так:
При передаче исходного объекта или набора запросов экземпляру сериализатора, объект будет доступен как .instance
. Если начальный объект не передан, то атрибут .instance
будет иметь значение None
.
При передаче данных экземпляру сериализатора, немодифицированные данные будут доступны как .initial_data
. Если именованный аргумент data
не передан, то атрибут .initial_data
не будет существовать.
По умолчанию сериализаторам должны передаваться значения для всех обязательных полей, иначе они будут выдавать ошибки валидации. Вы можете использовать аргумент partial
, чтобы разрешить частичное обновление.
Предыдущие примеры хорошо подходят для работы с объектами, которые имеют только простые типы данных, но иногда нам также необходимо иметь возможность представлять более сложные объекты, где некоторые атрибуты объекта могут не быть простыми типами данных, такими как строки, даты или целые числа.
Класс Serializer
сам является типом Field
и может быть использован для представления отношений, в которых один тип объекта вложен в другой.
Если вложенное представление может опционально принимать значение None
, вы должны передать флаг required=False
вложенному сериализатору.
Аналогично, если вложенное представление должно быть списком элементов, вы должны передать флаг many=True
в сериализатор вложенных элементов.
При работе с вложенными представлениями, поддерживающими десериализацию данных, любые ошибки с вложенными объектами будут вложены под именем поля вложенного объекта.
Аналогично, свойство .validated_data
будет включать в себя вложенные структуры данных.
Написание методов .create()
для вложенных представлений
Если вы поддерживаете записываемые вложенные представления, вам нужно написать методы .create()
или .update()
, которые обрабатывают сохранение нескольких объектов.
В следующем примере показано, как можно создать пользователя с вложенным объектом профиля.
Написание методов .update()
для вложенных представлений
Для обновлений вам необходимо тщательно продумать, как обрабатывать обновления отношений. Например, если данные для отношения None
, или не предоставлены, что из перечисленного ниже должно произойти?
Установите для отношения значение NULL
в базе данных.
Удалите связанный экземпляр.
Игнорировать данные и оставить экземпляр как есть.
Вызвать ошибку валидации.
Вот пример метода .update()
для нашего предыдущего класса UserSerializer
.
Поскольку поведение вложенных созданий и обновлений может быть неоднозначным и может требовать сложных зависимостей между связанными моделями, DRF 3 требует, чтобы вы всегда писали эти методы явно. Методы ModelSerializer
.create()
и .update()
по умолчанию не включают поддержку записываемых вложенных представлений.
Обработка сохранения связанных экземпляров в классах менеджера моделей
Альтернативой сохранению нескольких связанных экземпляров в сериализаторе является написание пользовательских классов менеджера модели, которые занимаются созданием нужных экземпляров.
Например, предположим, мы хотим, чтобы экземпляры User
и Profile
всегда создавались вместе как пара. Мы можем написать пользовательский класс менеджера, который будет выглядеть примерно так:
Этот класс менеджера теперь более точно передает, что экземпляры пользователя и профиля всегда создаются одновременно. Наш метод .create()
в классе сериализатора теперь может быть переписан для использования нового метода менеджера.
Класс Serializer
также может обрабатывать сериализацию или десериализацию списков объектов.
Сериализация нескольких объектов
Чтобы сериализовать кверисет или список объектов вместо одного экземпляра объекта, необходимо передать флаг many=True
при инстанцировании сериализатора. Затем вы можете передать кверисет или список объектов для сериализации.
Десериализация нескольких объектов
Бывают случаи, когда вам необходимо предоставить сериализатору дополнительный контекст в дополнение к сериализуемому объекту. Одним из распространенных случаев является использование сериализатора, который включает отношения с гиперссылками, что требует, чтобы сериализатор имел доступ к текущему запросу, чтобы он мог правильно генерировать полностью определенные URL.
Вы можете предоставить произвольный дополнительный контекст, передав аргумент context
при инстанцировании сериализатора. Например:
Контекстный словарь можно использовать в любой логике поля сериализатора, например, в пользовательском методе .to_representation()
, обращаясь к атрибуту self.context
.
Часто вам понадобятся классы сериализаторов, которые близко сопоставляются с определениями моделей Django.
Класс ModelSerializer
предоставляет ярлык, позволяющий автоматически создать класс Serializer
с полями, соответствующими полям модели.
Класс ModelSerializer
такой же, как и обычный класс Serializer
, за исключением того, что:
Он автоматически сгенерирует для вас набор полей на основе модели.
Он автоматически генерирует валидаторы для сериализатора, такие как валидаторы unique_together.
Он включает простые реализации по умолчанию .create()
и .update()
.
Объявление ModelSerializer
выглядит следующим образом:
По умолчанию все поля модели класса будут отображены на соответствующие поля сериализатора.
Проверка ModelSerializer
.
Классы сериализаторов генерируют полезные строки представления, которые позволяют полностью просмотреть состояние их полей. Это особенно полезно при работе с ModelSerializers
, когда вы хотите определить, какой набор полей и валидаторов автоматически создается для вас.
Для этого откройте оболочку Django, используя python manage.py shell
, затем импортируйте класс сериализатора, инстанцируйте его и выведите представление объекта...
Если вы хотите, чтобы в сериализаторе модели использовалось только подмножество полей по умолчанию, вы можете сделать это с помощью опций fields
или exclude
, как и в случае с ModelForm
. Настоятельно рекомендуется явно задавать все поля, которые должны быть сериализованы, с помощью атрибута fields
. Это уменьшит вероятность непреднамеренного раскрытия данных при изменении ваших моделей.
Например:
Вы также можете установить для атрибута fields
специальное значение '__all__'
, чтобы указать, что должны использоваться все поля в модели.
Например:
Вы можете установить атрибут exclude
в список полей, которые должны быть исключены из сериализатора.
Например:
В приведенном выше примере, если модель Account
имеет 3 поля account_name
, users
и created
, это приведет к тому, что поля account_name
и created
будут сериализованы.
Имена в атрибутах fields
и exclude
обычно отображаются на поля модели в классе модели.
Альтернативные имена в опциях fields
могут отображаться на свойства или методы, не принимающие аргументов, которые существуют в классе модели.
Начиная с версии 3.3.0, обязательным является предоставление одного из атрибутов fields
или exclude
.
По умолчанию ModelSerializer
использует первичные ключи для отношений, но вы также можете легко генерировать вложенные представления с помощью опции depth
:
Параметр depth
должен быть установлен в целочисленное значение, которое указывает глубину отношений, которые должны быть пройдены перед возвратом к плоскому представлению.
Если вы хотите настроить способ сериализации, вам нужно будет определить поле самостоятельно.
Вы можете добавить дополнительные поля в ModelSerializer
или переопределить поля по умолчанию, объявив поля в классе, как и в классе Serializer
.
Дополнительные поля могут соответствовать любому свойству или вызываемому объекту модели.
Вы можете указать несколько полей как доступные только для чтения. Вместо того чтобы добавлять каждое поле явно с атрибутом read_only=True
, вы можете использовать сокращенную опцию Meta, read_only_fields
.
Этот параметр должен представлять собой список или кортеж имен полей и объявляется следующим образом:
Поля модели, для которых установлено значение editable=False
, и поля AutoField
по умолчанию будут установлены в режим только для чтения, и их не нужно добавлять в опцию read_only_fields
.
Примечание: Существует особый случай, когда поле, доступное только для чтения, является частью ограничения unique_together
на уровне модели. В этом случае поле требуется классу сериализатора для проверки ограничения, но также не должно редактироваться пользователем.
Правильный способ справиться с этим - явно указать поле в сериализаторе, предоставив именованные аргументы read_only=True
и default=...
.
Одним из примеров этого является отношение только для чтения к текущему аутентифицированному User
, который является unique_together
с другим идентификатором. В этом случае вы объявите поле пользователя следующим образом:
Также есть возможность указать произвольные дополнительные именованные аргументы для полей, используя опцию extra_kwargs
. Как и в случае с read_only_fields
, это означает, что вам не нужно явно объявлять поле в сериализаторе.
Эта опция представляет собой словарь, отображающий имена полей на словарь именованных аргументов. Например:
Следует помнить, что если поле уже было явно объявлено в классе сериализатора, то опция extra_kwargs
будет проигнорирована.
При сериализации экземпляров модели существует несколько различных способов представления отношений. Представление по умолчанию для ModelSerializer
заключается в использовании первичных ключей связанных экземпляров.
Альтернативные представления включают сериализацию с помощью гиперссылок, сериализацию полных вложенных представлений или сериализацию с помощью пользовательского представления.
Класс ModelSerializer также предоставляет API, который вы можете переопределить, чтобы изменить способ автоматического определения полей сериализатора при инстанцировании сериализатора.
Обычно, если ModelSerializer
не генерирует нужные вам поля по умолчанию, вы должны либо добавить их в класс явно, либо просто использовать вместо них обычный класс Serializer
. Однако в некоторых случаях вы можете захотеть создать новый базовый класс, определяющий, как создаются поля сериализатора для любой конкретной модели.
serializer_field_mapping
.Отображение полей модели Django на поля сериализатора DRF. Вы можете переопределить это отображение, чтобы изменить поля сериализатора по умолчанию, которые должны использоваться для каждого поля модели.
serializer_related_field
.Это свойство должно быть классом поля сериализатора, который по умолчанию используется для реляционных полей.
Для ModelSerializer
это значение по умолчанию равно serializers.PrimaryKeyRelatedField
.
Для HyperlinkedModelSerializer
это значение по умолчанию равно serializers.HyperlinkedRelatedField
.
serializer_url_field
.Класс поля сериализатора, который должен использоваться для любого поля url
в сериализаторе.
По умолчанию serializers.HyperlinkedIdentityField
.
serializer_choice_field
Класс поля сериализатора, который должен использоваться для любых полей выбора в сериализаторе.
По умолчанию serializers.ChoiceField
.
Следующие методы вызываются для определения класса и именованных аргументов для каждого поля, которое должно быть автоматически включено в сериализатор. Каждый из этих методов должен возвращать кортеж (field_class, field_kwargs)
.
build_standard_field(self, field_name, model_field)
.Вызывается для генерации поля сериализатора, которое сопоставляется со стандартным полем модели.
Реализация по умолчанию возвращает класс сериализатора на основе атрибута serializer_field_mapping
.
build_relational_field(self, field_name, relation_info)
.Вызывается для генерации поля сериализатора, которое сопоставляется с полем реляционной модели.
Реализация по умолчанию возвращает класс сериализатора на основе атрибута serializer_related_field
.
Аргумент relation_info
представляет собой именованный кортеж, содержащий свойства model_field
, related_model
, to_many
и has_through_model
.
build_nested_field(self, field_name, relation_info, nested_depth)
.Вызывается для генерации поля сериализатора, которое сопоставляется с полем реляционной модели, если установлен параметр depth
.
Реализация по умолчанию динамически создает вложенный класс сериализатора на основе ModelSerializer
или HyperlinkedModelSerializer
.
Значение nested_depth
будет равно значению опции depth
, минус один.
Аргумент relation_info
представляет собой именованный кортеж, содержащий свойства model_field
, related_model
, to_many
и has_through_model
.
build_property_field(self, field_name, model_class)
.Вызывается для генерации поля сериализатора, которое сопоставляется со свойством или методом с нулевым аргументом класса модели.
Реализация по умолчанию возвращает класс ReadOnlyField
.
build_url_field(self, field_name, model_class)
.Вызывается для генерации поля сериализатора для собственного поля сериализатора url
. Реализация по умолчанию возвращает класс HyperlinkedIdentityField
.
build_unknown_field(self, field_name, model_class)
.Вызывается, когда имя поля не сопоставлено ни с одним полем модели или свойством модели. Реализация по умолчанию вызывает ошибку, хотя подклассы могут настраивать это поведение.
Класс HyperlinkedModelSerializer
похож на класс ModelSerializer
, за исключением того, что он использует гиперссылки для представления отношений, а не первичные ключи.
По умолчанию сериализатор будет включать поле url
вместо поля первичного ключа.
Поле url будет представлено с помощью поля сериализатора HyperlinkedIdentityField
, а любые отношения в модели будут представлены с помощью поля сериализатора HyperlinkedRelatedField
.
Вы можете явно включить первичный ключ, добавив его, например, в опцию fields
:
При инстанцировании HyperlinkedModelSerializer
вы должны включить текущий request
в контекст сериализатора, например:
Это гарантирует, что гиперссылки будут содержать соответствующее имя хоста, чтобы в результирующем представлении использовались полные URL-адреса, например:
Вместо относительных URL-адресов, таких как:
Если вы хотите использовать относительные URL, вы должны явно передать {'request': None}
в контексте сериализатора.
Необходимо определить, какие представления следует использовать для гиперссылок на экземпляры модели.
По умолчанию ожидается, что гиперссылки будут соответствовать имени представления, которое соответствует стилю '{имя_модели}-detail'
, и ищет экземпляр по именованному аргументу pk
.
Вы можете переопределить имя представления поля URL и поле поиска, используя один или оба параметра view_name
и lookup_field
в параметре extra_kwargs
, как показано ниже:
В качестве альтернативы вы можете явно задать поля в сериализаторе. Например:
Совет: Правильное согласование гиперссылочных представлений и вашего URL conf иногда может быть немного сложным. Печать repr
экземпляра HyperlinkedModelSerializer
- особенно полезный способ проверить, какие именно имена представлений и поля поиска должны отображать отношения.
Имя поля URL по умолчанию равно 'url'. Вы можете переопределить его глобально, используя параметр URL_FIELD_NAME
.
Класс ListSerializer
обеспечивает поведение для сериализации и валидации нескольких объектов одновременно. Обычно вам не нужно использовать ListSerializer
напрямую, а следует просто передать many=True
при инстанцировании сериализатора.
При инстанцировании сериализатора и передаче many=True
будет создан экземпляр ListSerializer
. Затем класс сериализатора становится дочерним классом родительского ListSerializer
.
Следующий аргумент также может быть передан полю ListSerializer
или сериализатору, которому передано many=True
:
allow_empty
По умолчанию это True
, но может быть установлено в False
, если вы хотите запретить пустые списки в качестве допустимого ввода.
max_length
По умолчанию это None
, но может быть установлено в положительное целое число, если вы хотите проверить, что список содержит не более этого количества элементов.
min_length
По умолчанию это None
, но может быть установлено в положительное целое число, если вы хотите проверить, что список содержит не менее этого количества элементов.
ListSerializer
.Существует несколько случаев, когда вы захотите настроить поведение ListSerializer
. Например:
Вы хотите обеспечить определенную проверку списков, например, проверить, что один элемент не конфликтует с другим элементом списка.
Вы хотите настроить поведение создания или обновления нескольких объектов.
Для этих случаев вы можете изменить класс, который используется при передаче many=True
, используя опцию list_serializer_class
для класса сериализатора Meta
.
Например:
Настройка множественного создания
Реализация по умолчанию для создания нескольких объектов заключается в простом вызове .create()
для каждого элемента списка. Если вы хотите настроить это поведение, вам нужно настроить метод .create()
класса ListSerializer
, который используется, когда передается many=True
.
Например:
Настройка многократного обновления
По умолчанию класс ListSerializer
не поддерживает множественные обновления. Это связано с тем, что поведение, которое следует ожидать для вставок и удалений, неоднозначно.
Для поддержки нескольких обновлений необходимо сделать это явно. При написании кода множественных обновлений обязательно учитывайте следующее:
Как определить, какой экземпляр должен быть обновлен для каждого элемента в списке данных?
Как следует обрабатывать вставки? Являются ли они недействительными, или они создают новые объекты?
Как следует обрабатывать удаления? Означают ли они удаление объекта или удаление отношения? Следует ли их молча игнорировать, или они недействительны?
Как следует обрабатывать упорядочивание? Влечет ли изменение положения двух объектов изменение состояния или оно игнорируется?
Вам нужно будет добавить явное поле id
в сериализатор экземпляра. По умолчанию неявно генерируемое поле id
помечено как read_only
. Это приводит к тому, что оно удаляется при обновлении. Как только вы объявите его явно, оно будет доступно в методе update
сериализатора списка.
Вот пример того, как можно реализовать несколько обновлений:
Настройка инициализации ListSerializer
Когда инстанцируется сериализатор с many=True
, нам необходимо определить, какие аргументы и ключевые слова следует передать в метод .__init__()
как для дочернего класса Serializer
, так и для родительского класса ListSerializer
.
По умолчанию все аргументы передаются обоим классам, за исключением validators
и любых пользовательских именованных аргументов, которые, как предполагается, предназначены для дочернего класса сериализатора.
Иногда вам может понадобиться явно указать, как дочерний и родительский классы должны быть инстанцированы при передаче many=True
. Вы можете сделать это с помощью метода класса many_init
.
Класс BaseSerializer
, который можно использовать для простой поддержки альтернативных стилей сериализации и десериализации.
Этот класс реализует тот же базовый API, что и класс Serializer
:
.data
- Возвращает исходящее примитивное представление.
.is_valid()
- Десериализует и проверяет входящие данные.
.validated_data
- Возвращает проверенные входящие данные.
.errors
- Возвращает любые ошибки во время валидации.
.save()
- Сохраняет проверенные данные в экземпляре объекта.
Есть четыре метода, которые могут быть переопределены, в зависимости от того, какую функциональность вы хотите, чтобы поддерживал класс сериализатора:
.to_representation()
- Переопределить это для поддержки сериализации, для операций чтения.
.to_internal_value()
- Переопределить это для поддержки десериализации, для операций записи.
.create()
и .update()
- Переопределите один из этих параметров или оба для поддержки сохранения экземпляров.
Поскольку этот класс предоставляет тот же интерфейс, что и класс Serializer
, вы можете использовать его с существующими общими представлениями на основе классов точно так же, как и обычный Serializer
или ModelSerializer
.
Единственное отличие, которое вы заметите при этом - классы BaseSerializer
не будут генерировать HTML-формы в Web-интерфейсе API. Это происходит потому, что данные, которые они возвращают, не включают всю информацию о полях, которая позволит преобразовать каждое поле в подходящий HTML-ввод.
Классы BaseSerializer
только для чтения.
Чтобы реализовать сериализатор только для чтения, используя класс BaseSerializer
, нам просто нужно переопределить метод .to_representation()
. Давайте рассмотрим пример на примере простой модели Django:
Очень просто создать сериализатор только для чтения для преобразования экземпляров HighScore
в примитивные типы данных.
Теперь мы можем использовать этот класс для сериализации отдельных экземпляров HighScore
:
Или используйте его для сериализации нескольких экземпляров:
Классы BaseSerializer
с функцией чтения-записи
Для создания сериализатора чтения-записи нам сначала нужно реализовать метод .to_internal_value()
. Этот метод возвращает проверенные значения, которые будут использованы для создания экземпляра объекта, и может вызвать serializers.ValidationError
, если предоставленные данные имеют неправильный формат.
Как только вы реализуете .to_internal_value()
, базовый API валидации будет доступен в сериализаторе, и вы сможете использовать .is_valid()
, .validated_data
и .errors
.
Если вы хотите также поддерживать .save()
, вам необходимо также реализовать один или оба метода .create()
и .update()
.
Вот полный пример нашего предыдущего HighScoreSerializer
, который был обновлен для поддержки операций чтения и записи.
Создание новых базовых классов
Класс BaseSerializer
также полезен, если вы хотите реализовать новые общие классы сериализаторов для работы с определенными стилями сериализации или для интеграции с альтернативными бэкендами хранения данных.
Следующий класс является примером общего сериализатора, который может обрабатывать принудительное преобразование произвольных сложных объектов в примитивные представления.
Если вам нужно изменить поведение сериализации или десериализации класса сериализатора, вы можете сделать это, переопределив методы .to_representation()
или .to_internal_value()
.
Некоторые причины, по которым это может быть полезно, включают...
Добавление нового поведения для новых базовых классов сериализаторов.
Небольшое изменение поведения для существующего класса.
Улучшение производительности сериализации для часто используемой конечной точки API, которая возвращает много данных.
Подписи для этих методов следующие:
to_representation(self, instance)
.
Принимает экземпляр объекта, который требует сериализации, и должен вернуть примитивное представление. Обычно это означает возврат структуры встроенных в Python типов данных. Точные типы, которые могут быть обработаны, зависят от классов рендеринга, которые вы настроили для своего API.
Может быть переопределена для изменения стиля представления. Например:
to_internal_value(self, data)
.
Принимает невалидированные входящие данные в качестве входных и должен вернуть валидированные данные, которые будут доступны как serializer.validated_data
. Возвращаемое значение также будет передано в методы .create()
или .update()
, если для класса сериализатора будет вызван .save()
.
Аргумент data
, передаваемый этому методу, обычно является значением request.data
, поэтому тип данных, который он предоставляет, будет зависеть от классов парсера, которые вы настроили для своего API.
Подобно формам Django, вы можете расширять и повторно использовать сериализаторы с помощью наследования. Это позволяет вам объявить общий набор полей или методов в родительском классе, который затем может быть использован в нескольких сериализаторах. Например,
Как и классы Model
и ModelForm
в Django, внутренний класс Meta
в сериализаторах не наследуется неявно от внутренних классов Meta
своих родителей. Если вы хотите, чтобы класс Meta
наследовался от родительского класса, вы должны сделать это явно. Например:
Обычно мы рекомендуем не использовать наследование для внутренних классов Meta, а вместо этого объявлять все опции явно.
Кроме того, следующие предостережения относятся к наследованию сериализаторов:
Применяются обычные правила разрешения имен Python. Если у вас есть несколько базовых классов, которые объявляют внутренний класс Meta
, будет использоваться только первый класс. Это означает дочерний Meta
, если он существует, иначе Meta
первого родителя и т.д.
Можно декларативно удалить Field
, унаследованный от родительского класса, указав значение None
в подклассе.
После инициализации сериализатора, к словарю полей, установленных в сериализаторе, можно получить доступ с помощью атрибута .fields
. Доступ и изменение этого атрибута позволяет динамически модифицировать сериализатор.
Изменение аргумента fields
напрямую позволяет вам делать такие интересные вещи, как изменение аргументов полей сериализатора во время выполнения, а не в момент объявления сериализатора.
Например, если вы хотите иметь возможность установить, какие поля должны использоваться сериализатором в момент его инициализации, вы можете создать класс сериализатора следующим образом:
Это позволит вам сделать следующее:
REST framework 2 предоставил API, позволяющий разработчикам переопределять, как класс ModelSerializer
будет автоматически генерировать набор полей по умолчанию.
Этот API включал методы .get_field()
, .get_pk_field()
и другие.
Поскольку сериализаторы были кардинально переработаны в версии 3.0, этот API больше не существует. Вы все еще можете изменять создаваемые поля, но вам придется обратиться к исходному коду, и имейте в виду, что если изменения, которые вы делаете, направлены против частных частей API, то они могут быть изменены.
Также доступны следующие пакеты сторонних производителей.
Для получения дополнительной информации см. документацию .
Однако существуют сторонние пакеты, такие как , которые поддерживают автоматические записываемые вложенные представления.
Более подробно об этом подходе смотрите документацию Django по , и .
Поведение по умолчанию для десериализации нескольких объектов - это поддержка создания нескольких объектов, но не поддержка обновления нескольких объектов. Для получения дополнительной информации о том, как поддержать или настроить любой из этих случаев, см. документацию по ниже.
Любые отношения, такие как внешние ключи в модели, будут отображены на PrimaryKeyRelatedField
. Обратные отношения не включаются по умолчанию, если они не включены явно, как указано в документации .
Пожалуйста, ознакомьтесь с документацией для получения подробной информации о классах и .
Более подробную информацию можно найти в документации .
Если какая-либо из валидаций не прошла, то метод должен вызвать serializers.ValidationError(errors)
. Аргумент errors
должен представлять собой словарь, отображающий имена полей (или settings.NON_FIELD_ERRORS_KEY
) на список сообщений об ошибках. Если вам не нужно изменять поведение десериализации и вместо этого вы хотите обеспечить проверку на уровне объекта, рекомендуется переопределить метод .
Однако вы можете использовать эту технику только для отказа от поля, определенного декларативно родительским классом; это не помешает ModelSerializer
сгенерировать поле по умолчанию. Чтобы отказаться от полей по умолчанию, смотрите .
Пакет предоставляет альтернативную реализацию сериализаторов, используя библиотеку python . Он предоставляет тот же API, что и сериализаторы DRF, и может быть использован в качестве замены в некоторых случаях.
Пакет - это альтернативная реализация сериализаторов, созданная для скорости. сериализует сложные типы данных в простые нативные типы. Родные типы могут быть легко преобразованы в JSON или любой другой необходимый формат.
Пакет предоставляет класс сериализатора MongoEngineModelSerializer
, который поддерживает использование MongoDB в качестве уровня хранения данных для DRF.
Пакет предоставляет класс сериализатора GeoFeatureModelSerializer
, который поддерживает GeoJSON как для операций чтения, так и для записи.
Пакет предоставляет HStoreSerializer
для поддержки поля модели DictionaryField
и его функции chema-mode
.
Пакет расширяет интерфейсы ModelSerializer и ModelViewSet, добавляя параметры запроса API для фильтрации, сортировки, включения/исключения всех полей и отношений, определенных вашими сериализаторами.
Пакет предоставляет миксин для динамического ограничения полей для сериализатора подмножеством, заданным параметром URL.
Пакет расширяет ModelSerializer и ModelViewSet для обеспечения широко используемой функциональности для динамической установки полей и расширения примитивных полей во вложенные модели, как из параметров URL, так и из определений класса вашего сериализатора.
Пакет предоставляет набор инструментов для DRY up ваших сериализаторов, позволяя определять поля на основе каждого представления/запроса. Поля могут быть внесены в белый или черный список, а дочерние сериализаторы могут быть расширены по желанию.
Пакет предоставляет алгоритм и сериализатор для обработки <form>
в соответствии с (неактивной) . Сериализатор облегчает обработку произвольно вложенных структур JSON в HTML. Например, <input name="items[0][id]" value="5">
будет интерпретирован как {"items": [{"id": "5"}]}
.
предоставляет набор сериализаторов полей и моделей, который обрабатывает загрузку файлов в base64-кодировке.
позволяет клиентам API указать, какие поля будут отправлены в ответе с помощью параметров запроса включения/исключения.
Пакет предоставляет записываемый сериализатор вложенных моделей, который позволяет создавать/обновлять модели с вложенными связанными данными.
Пакет помогает вам шифровать данные, сериализованные через ModelSerializer
. Он также содержит некоторые вспомогательные функции. Это поможет вам зашифровать ваши данные.