Фреймворк Django REST (DRF) в Python — как использовать
В этом руководстве вы узнаете о Django REST Framework и о том, как использовать его для создания простого, но полного RESTful API, управляющего задачами в Python.
- Введение в фреймворк Django REST
- Установка пакета Django REST Framework
- Создание нового приложения на основе Django REST
- Создание класса сериализатора
- Сериализация данных
- Создание класса представления API
- Определение конечных точек API
- Взаимодействие с API с использованием Browsable API
- Получение всех задач
- Создание новой задачи
- Получение конкретной задачи
- Обновление задачи
- Удаление задачи
Введение в фреймворк Django REST
Django REST Framework или DRF — это мощный инструментарий для разработки веб-API в приложениях Django. DRF позволяет быстро создавать RESTful API, предоставляя готовые классы и соглашения.
DRF имеет следующие ключевые особенности:
- Сериализация: позволяет автоматически преобразовывать модели Django в JSON и наоборот, обеспечивая бесперебойную передачу данных между клиентом и сервером.
- Маршрутизация URL: DRF обеспечивает маршрутизацию URL, аналогичную маршрутизатору Django, что позволяет эффективно связывать URL-адреса с представлениями API.
- Аутентификация: DRF предлагает различные методы аутентификации, включая базовую аутентификацию и аутентификацию токенов. Он также поддерживает JWT через сторонний пакет.
- Разрешение: DRF обеспечивает детальный контроль над разрешениями пользователей.
- Регулирование/Ограничение скорости: функции регулирования и скорости помогают ограничить количество запросов, которые клиент может сделать в течение определенного периода времени.
- Пагинация: DRF обеспечивает встроенную поддержку пагинации больших наборов данных в ответах API.
- API с возможностью просмотра: DRF имеет удобный HTML-интерфейс для тестирования и изучения API непосредственно из браузера.
Установка пакета Django REST Framework
Сначала установите фреймворк Django REST в виртуальную среду проекта:
pip install djangorestframework
Во-вторых, обновите файл requirements.txt:
pip freeze > requirements.txt
В-третьих, зарегистрируйте приложение rest_framework в settings.py проекта:
INSTALLED_APPS = [ ... 'rest_framework', ... ]
Создание нового приложения на основе Django REST
Создайте новый каталог с именем api в каталоге проекта для размещения кода API:
mkdir api
Во-вторых, создайте три файла Python внутри каталога api:
- serializers.py – предоставляет сериализатор, который преобразует модели Django в формат JSON и наоборот.
- views.py – содержит представления API, аналогичные представлениям приложения Django.
- urls.py – определяет конечную точку API, которая сопоставляется с представлениями API.
В-третьих, добавьте API в INSTALLED_APPS в файле settings.py проекта:
INSTALLED_APPS = [ ... 'api', ... ]
Мы создадим API со следующими конечными точками:
Конечные точки | HTTP Verb | Описание |
---|---|---|
API/v1/todos/ | GET | Вернуть все задачи |
API/v2/todos/ | POST | Создать новую задачу |
API/v2/todos/1 | GET | Вернуть задачу с идентификатором 1 |
API/v1/todos/1 | PATCH | Обновить задачу с идентификатором 1 |
API/v1/todos/1 | DELETE | Удалить задачу с идентификатором 1 |
Создание класса сериализатора
Классы сериализаторов позволяют сериализовать экземпляры моделей Django в JSON и наоборот.
Ниже определяется класс сериализатора TodoSerializer в файле serializers.py, который сериализует экземпляр Todo в JSON и наоборот:
from rest_framework import serializers from todo.models import Todo class TodoSerializer(serializers.ModelSerializer): user = serializers.StringRelatedField(read_only=True) class Meta: model = Todo fields =('id', 'title', 'completed', 'user')
Как это работает.
Сначала импортируем модуль сериализаторов из пакета rest_framework:
from rest_framework import serializers
Во-вторых, импортируйте модель Todo из модуля моделей приложения Todo:
from todo.models import Todo
В-третьих, определите класс TodoSerializer, который расширяет класс serializers.ModelSerializer:
class TodoSerializer(serializers.ModelSerializer): ...
ModelSerializer предоставляет быстрый способ определения класса сериализатора с полями, соответствующими полям модели.
Внутри класса TodoSerializer определите класс Meta, который инициализирует:
- model – определяет модель Todo.
- fields – указывает список полей для сериализатора. Если сериализатор использует все поля модели, вы можете использовать ‘__all__’ вместо этого, например:
fields = '__all__'
Поскольку модель Todo связана с моделью User, мы указываем атрибут user как StringRelatedField() и устанавливаем его параметр на read_only. Это означает, что задача будет иметь строковое представление пользователя, которое в данном случае является именем пользователя.
Параметр read_only позволяет сериализатору только читать модель User. Другими словами, сериализатор не сможет обновить модель User.
Помимо StringRelatedField, DRF предоставляет другие типы связанных полей, как показано в следующей таблице:
Поле | Описание |
---|---|
PrimaryKeyRelatedField | Представляет связанную модель в качестве первичного ключа. |
HyperlinkedRelatedField | Представляет связанную модель в виде гиперссылки. |
SlugRelatedField | Представляет соответствующую модель как одно из ее полей. |
HyperlinkedIdentityField | Представляет связанную модель в виде гиперссылки на поле идентификации. |
Поскольку мы завершили определение класса Serializer, давайте используем его для сериализации модели Todo с помощью класса TodoSerializer в оболочке Django.
Сериализация данных
Сначала запустите Django Shell из терминала:
python manage.py shell
Во-вторых, импортируйте модель Todo и класс TodoSerializer:
>>> from api.serializers import TodoSerializer >>> from todo.models import Todo
В-третьих, получите Todo с идентификатором 1:
>> todo = Todo.objects.get(id=1) >>> todo <Todo: Learn Python>
В-четвертых, создайте новый экземпляр TodoSerializer с моделью Todo и получите доступ к атрибуту data:
>>> serializer = TodoSerializer(todo) >>> serializer.data {'id': 1, 'title': 'Learn Python', 'completed': False, 'user': 'john'}
Объект TodoSerialzier сериализует модель задач в формат JSON.
Создание класса представления API
Ниже приведены определения классов представлений API в файле views.py:
from rest_framework import generics from .serializers import TodoSerializer from todo.models import Todo class TodoList(generics.ListCreateAPIView): queryset = Todo.objects.all() serializer_class = TodoSerializer def perform_create(self, serializer): serializer.save(user=self.request.user) class TodoDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Todo.objects.all() serializer_class = TodoSerializer
Как это работает.
Сначала импортируем дженерики из rest_framework:
from rest_framework import generics
Универсальные типы предоставляют различные базовые классы представлений, такие как ListCreateAPIView и RetrieveUpdateDestroyAPIView.
Во-вторых, импортируйте TodoSerializer из сериализаторов приложения API и модель Todo из моделей приложения Todo:
from .serializers import TodoSerializer from todo.models import Todo
В-третьих, определите класс TodoList, который расширяет класс ListCreateAPIView. Класс TodoList отвечает за две задачи:
- Перечислите все задачи.
- Создайте новую задачу.
class TodoList(generics.ListCreateAPIView): queryset = Todo.objects.all() serializer_class = TodoSerializer def perform_create(self, serializer): serializer.save(user=self.request.user)
В классе TodoList укажите набор запросов, используемый для возврата всех задач, и serializer_class, используемый для сериализации/десериализации экземпляров Todo. Метод perform_create() класса TodoSerializer вызывается автоматически при сохранении нового экземпляра Todo.
Поскольку каждому экземпляру Todo необходим экземпляр User, мы назначаем пользователя из HTTP-запроса(request) атрибуту user экземпляра Todo перед его сохранением в базе данных.
Наконец, определите класс TodoDetail, который расширяет класс RetrieveUpdateDestroyAPIView:
class TodoDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Todo.objects.all() serializer_class = TodoSerializer
Класс TodoDetail отвечает за следующие операции:
- Получить задачу по идентификатору.
- Обновить существующую задачу.
- Уничтожить(или удалить) задачу.
В классе TodoDetail нам также необходимо определить queryset и serializer_class.
Определение конечных точек API
Ниже приведены определения конечных точек API в urls.py приложения API:
from django.urls import path from .views import TodoList, TodoDetail urlpatterns = [ path('todos/', TodoList.as_view(), name='todo_list'), path('todos/<int:pk>/', TodoDetail.as_view(), name='todo_detail'), ]
Взаимодействие с API с использованием Browsable API
Django REST Framework поддерживает создание удобных для пользователя HTML-страниц всех ресурсов при запросе HTML-формата.
Эти страницы позволяют вам легко просматривать API и отправлять данные в конечные точки API с помощью POST, PUT, PATCH и DELETE.
Получение всех задач
Откройте конечную точку http://localhost:8000/api/v1/todos/, и вы увидите следующую страницу.
Открывая api/v1/todos/ в веб-браузере, вы выполняете запрос GET к конечной точке. Страница возвращает список todos в красиво отформатированной HTML-странице.
Чтобы получить необработанный формат JSON, укажите формат запроса GET, щелкнув пункт меню json в кнопке GET, как показано на следующем рисунке:
API вернет необработанный JSON:
[{"id":1,"title":"Learn Python","completed":false,"user":"john"},{"id":2,"title":"Study Django","completed":false,"user":"john"},{"id":3,"title":"Master Django REST API","completed":false,"user":"john"}]
Если в вашем веб-браузере установлено расширение для просмотра JSON, вы можете увидеть понятный человеку формат JSON следующим образом:
[ { "id": 1, "title": "Learn Python", "completed": false, "user": "john" }, { "id": 2, "title": "Study Django", "completed": false, "user": "john" }, { "id": 3, "title": "Master Django REST API", "completed": false, "user": "john" } ]
Создание новой задачи
Откройте конечную точку /api/v1/todos/. Но на этот раз мы отправим запрос POST вместо запроса GET.
Сначала введите информацию о задачах:
Во-вторых, нажмите кнопку POST, и вы получите следующий ответ:
API создает новую задачу с идентификатором 4. Кроме того, пользователь — это тот, под чьим именем вы в данный момент вошли в систему.
Обратите внимание, что вам необходимо войти на сайт администратора как пользователь, например, john, чтобы метод perform_create() TodoList мог получить информацию о пользователе из запроса.
Получение конкретной задачи
Откройте конечную точку /api/v1/todos/4/, чтобы получить подробную информацию о задаче с идентификатором 4:
В этом случае мы делаем запрос GET к конечной точке API /api/v1/todos/4/
Обновление задачи
Страница обновления задачи также является страницей, на которой отображаются подробные сведения о задаче.
Откройте конечную точку /api/v1/todos/4/, чтобы получить подробную информацию о задаче с идентификатором 4, и прокрутите страницу вниз до HTML-формы:
Во-вторых, измените некоторые значения Todo JSON и нажмите кнопку PUT, чтобы отправить запрос PUT, и вы получите следующий ответ:
Удаление задачи
Откройте конечную точку, чтобы просмотреть задачу с идентификатором 4: /api/v1/todos/4/ и нажмите кнопку «Удалить»:
Будет выведен запрос на подтверждение удаления:
Если вы нажмете кнопку «Delete», вы получите следующий ответ:
API отправил запрос DELETE к конечной точке и вернул HTTP-статус 204, указывающий на то, что задача была успешно удалена.