10 лайфхаков для Django REST Framework. Часть 1


В этой статье мы поделимся несколькими идеями и лайфхаками, которые облегчат вам работу с библиотекой Django REST Framework. Она работает со стандартными моделями Django и дает возможность создавать гибкие и мощные API. Все примеры, которые мы покажем в данной статье, совместимы с версией 3 DRF.


Логотип DRF 3

1. Viewsets (представления)

Начнем с простой функциональности Django REST Framework. Viewsets можно рассматривать как очень полезный шаблон для построения API, который обеспечивает типичные взаимодействия с моделями Django. В то время как обычные представления (views) действуют как обработчики для HTTP методов, viewsets дают вам возможность определить действия, такие как create – создание экземпляра или list– список экземпляров (со стандартной разбивкой по страницам).

Самое замечательное в viewsets – это то, как они делают ваш код последовательным и спасают от повторения. Каждый раз, когда вы пишете представления, которые выполняют более одной функции, viewsets позволит сделать это быстрее.

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

a. перечислить все теги;

b. создать новый тег;

c. получить подробную информацию о теге.

Вот так вы сможете определить viewset для вышеперечисленного:

Viewset mixins могут быть комбинированы по мере необходимости. Вы можете определить свои собственные mixins или использовать ModelViewSet, который позволяет выполнить следующие команды: .list(), .retrieve(), .create(), .update(), .partial_update() and .destroy().

Кроме того, при использовании viewsets обычно задействуются маршрутизаторы (routers) для конфигурации url. Составление именований url станет для вас хорошей практикой, что позволит сделать ваши URL-адреса API более предсказуемыми.

Теперь ваш viewset достаточно функционален, чтобы вы могли:

· составить список всех тегов, отправив GET запрос на v1/tag/;

· создать новый тег с помощью POST запроса на v1/tag/;

· или извлечь один из тегов используя GET v1/tag/.

Вы даже можете добавить произвольные действия квашему viewset, используя декоратор @action.

Теперь написание представлений завершено, и вы сохранили достаточно времени для чашечки кофе.

2. Понимание разных видов сериализаторов

Как DRF пользователю вам уже больше не нужно утруждать себя написанием представлений и url конфигурациями, потому что теперь у вас появится достаточно времени для сериализаторов, которые работают как трансляторы между примерами моделей Django и их репрезентациями (например, json). Существует несколько функций, связанных с сериализаторами, о которых вам стоит узнать.

Каждый сериализатор можно использовать как для чтения, так и для записи. То, как инициализируется сериализатор, определяет действие, которое он будет выполнять. Таким образом можно выделить 3 типа операций: создание экземпляра (create), обновление экземпляра (update), получение / чтение экземпляра (retrieve).

Если в представлении (view) вам нужно сериализировать данные, которые будет возвращать API, попробуйте следовать приведенным ниже действиям:

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

И наконец, во время обновления экземпляравам нужно передать параметр instance также, как data:

3. Использование SerializerMethodField

SerializerMethodField – поле для чтения, которое вычисляет свое значение во время обработки, вызывая метод сериализатора, к которому он присоединен. Предположим, что у вас есть модель, которая хранит данные о дате и времени в models.DateTimeField, но вы хотите использовать UNIX-формат в репрезентации сериализатора:

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

4. Использование параметра source

Довольно часто наименования полей в модели отличаются от требуемых в репрезентации. Использование параметра source позволит вам с легкостью с этим справится. Взглянем на пример:

Поле task_type находится в модели Task, но в вашем API это будет названо, как job_type. Это работает как для чтения, так и для написания операций.

Более того, вы можете использовать его для извлечения данных из связанных объектов при помощи точечной нотации:

5. Валидация поля сериализатора

Помимо аргумента validators, который можно передавать во время инициализации полей и хука serializer.validate(), также существует валидация на уровне полей, которая позволяет определить уникальный валидатор для каждого отдельного поля.

Есть две причины, по которым мы находим этот тип валидаторов полезным:

· он разделяет разные проверки, связанные только с определенным полем;

· он генерирует хорошо отформатированные ответы на ошибки.

Использование такого рода проверки аналогично использованию SerializerMethodField, но в этот раз применяется другая конвенция наименований: def validate_.

Вот пример:

Если bid превысит баланс пользователя, ответ на такой запрос будет выглядеть следующим образом:

Методы валидации всегда должны возвращать значение, которое позднее передается экземпляру метода. Учтите, что валидация полей вызывается в методе serializer.to_internal_value(), который используется перед командой serializer.validate().

О других лайфхаках мы расскажем в следующей публикации. Спасибо за ваши лайки и комментарии!

Перевод статьи Łukasz German.


Comments 0