10 лайфхаков для Django REST Framework. Часть 2
Продолжаем рассказывать о Django REST Framework. В предыдущей статье мы показали 5 лайфхаков при работе с этой библиотекой. Сейчас вы узнаете об остальных пяти.
Логотип DRF
6. Передача значения напрямую в метод save
В некоторых случаях удобно передавать значение извне сериализатора непосредственно к его методу save(). Этот метод принимает аргументы, которые могут быть приравнены к сериализованным объектам. Значения, переданные таким путем, не нуждаются в валидации. Они могут использоваться для переопределения исходных данных.
Например:
7. Использование CurrentUserDefault
Когда дело доходит до автоматической установки пользователя в качестве владельца данных, есть простой и удобный способ это осуществить – использовать класс CurrentUserDefault, который не требует переопределения представлений.
Данный класс выполняет две функции:
· пользователь, прошедший авторизацию (request.user), будет установлен по умолчанию;
· невозможно установить другого пользователя в качестве владельца из-за использования Hidden Field, так как в этом случае любые входящие данные не учитываются.
8. Исходные данные в сериализатороах
Иногда вам может потребоваться доступ к исходным данным, которые были переданы в сериализатор. Такая ситуация может возникнуть когда данные были изменены вызовом .is_valid (), или когда вам необходимо получить доступ к значению другого поля в валидаторе, но поле .validated_data еще не доступно. Для этих целей можно использовать поле serializer.initial_data, которое хранит исходные данные в виде словаря (dict).
Пример:
9. Вложенная сериализация
Сериализаторы довольно просты в использовании и при должном опыте вероятность того, что что-то пойдет не так, мала. Тем не менее, в сериализаторах есть несколько сложностей.
Всё может пойти наперекосяк в случае, когда вам потребуется создавать/обновлять/ удалять объекты во вложенных сериализаторах из одного высокоуровневого сериализатора. Такая задача возникает из компромисса: меньшее количество запросов за счет увеличенного времени обработки.
По умолчанию, Django REST Framework не поддерживает множественные обновления. Трудно представить, как библиотека может поддерживать все возможные типы вложенных вставок и удалений. Вот почему создатели DRF выбрали гибкость, а не готовое решение «из коробки», и оставили эту привилегию для вас.
Здесь есть 2 решения:
· использовать достаточно популярную стороннюю библиотеку DRF Writable Nested;
· сделать все самому.
Мы рекомендуем попробовать второй способ хотя бы раз, и вы узнаете как устроена вложенная сериализация «под капотом».
После анализа входных данных у вас появляется возможность сделать несколько предположений:
· все элементы, которые должны быть обновлены, имеют id;
· все элементы, которые должны быть созданы, не имеют id;
· все элементы, которые следует удалить, присутствуют в хранилище данных, но отсутствуют во входящем запросе request.data.
Основываясь на этих предположениях, мы знаем, что делать с каждым конкретным элементом. Ниже приведен фрагмент, который подробно показывает этот процесс:
Вот упрощенная версия того, как высокоуровневый сериализатор может использовать этот mixin:
Учтите, что вложенные объекты должны использовать исходные данные initial_data, а не validated_data. Это нужно потому, что запуск валидации вызывает field.to_internal_value() для каждого поля сериализатора, что может привести к изменению данных, хранящихся в поле (например, путем изменения первичного ключа для экземпляра модели).
10.Переопределение свойства data для принудительного упорядочивания
По умолчанию, QuerySet не упорядочены вовсе. Упорядочение в списочном представлении (listview) может быть легко выполнено путем добавления сортировки для параметра queryset нашего view. Но в случае, когда вложенные ресурсы также должны быть упорядочены, это не так просто.
Для полей, предназначенных только для чтения, это можно сделать с помощью Serializer Method Field, но что делать в ситуации, когда поле должно быть доступно для записи?
В таком случае можно переопределить свойство data в сериализаторе, как показано в этом примере:
Спасибо за лайки и комментарии! Надеемся, наши советы будут для вас полезными.
Перевод статьи Łukasz German.