Django REST Framework: быстрое начало работы
Оглавление
- TL;DR Django REST Framework
- Введение в Django REST Framework
- TL;DR: Давайте начнем быстро
- Заключение
TL;DR Django REST Framework
Если вы не интересуетесь тонкостями работы Django REST Framework (DRF), просто перейдите к обучающей части, чтобы узнать, как за пять минут или меньше создать свой API. После этого вернитесь и ознакомьтесь с деталями того, как составлена каждая часть учебника по DRF и какие дополнительные возможности и функциональность вы можете получить от DRF.
Введение в REST-фреймворк Django
Django REST Framework - это как Django для RESTful API. Он предоставляет столько возможностей из коробки, что, просто установив и подключив его к Django, вы получаете тонну функциональности без необходимости писать много кода вообще. Для больших и сложных проектов это огромное облегчение для тех, кто занимается поддержкой такого кода.
Django REST Framework поставляется с сериализаторами, которые могут напрямую заменить Django Forms для проверки и создания объектов на основе API, общими классами представлений для быстрого запуска конечных точек API, а также автоматически генерируемым браузерным API для любого из используемых вами представлений Django REST Framework.
Это лишь некоторые из замечательных возможностей, которые предоставляет Django REST Framework, и, как и в случае с Django и любым другим пакетом Python, вы можете взять те части, которые вам нужны, а остальное оставить в покое, что позволит вам легко справиться с такой задачей, как преобразование существующих API в Django REST Framework без необходимости изучения всего фреймворка.
Давайте вкратце рассмотрим некоторые моменты, которые делают Django REST Framework столь мощным.
Сериализаторы
Когда я только начал работать с Django REST Framework, у меня уже были собственные API, построенные с использованием Django Generic Views, и я испытывал трудности с сериализацией сложных данных. Импорт и использование сериализаторов Django REST Framework избавили меня от этой головной боли. Существует несколько различных сериализаторов, которые можно использовать, и каждый из них можно настраивать. Из коробки сериализаторы легко справляются со сложными экземплярами моделей Django, а API для использования сериализаторов интуитивно понятен и хорошо документирован.
Сериализаторы Django REST Framework настолько похожи на формы Django, что у вас не должно возникнуть проблем с их освоением. Давайте рассмотрим `ModelSerializer` из Django REST Framework и сравним его с Django ModelForm:
"""
Forms for Character model
"""
from django import forms
from characters.models import Character
class CharacterCreateView(forms.ModelForm):
class Meta:
model = Character
fields = ('name', 'description', 'profession', 'mentor', 'team', 'type',)
class CharacterUpdateView(forms.ModelForm):
class Meta:
model = Character
fields = ('name', 'description', 'profession', 'mentor', 'team', 'type',)
"""
Serializers for Character model
"""
from rest_framework import serializers
from characters.models import Character
class CharacterSerializer(serializers.ModelSerializer):
mentor = serializers.StringRelatedField()
team = serializers.StringRelatedField()
random_line = serializers.SerializerMethodField()
@staticmethod
def get_random_line(obj):
return obj.get_line()
class Meta:
model = Character
fields = (
'name', 'description', 'profession', 'mentor', 'team', 'type', 'random_line',
)
Вы видите, что определение практически идентично. Различия в этом простом примере заключаются в наличии StringRelatedField
полей и get_random_line
метода на CharacterSerializer
. Эти дополнительные элементы используются для добавления дополнительной информации в сериализованный вывод.
<1>> принимает StringRelatedField
связанную модель и выводит ее __str__
представление при сериализации, а get_random_line
вызывает метод модели и добавляет его в сериализованный вывод. Сериализаторы DRF позволяют настраивать, добавлять и исключать из сериализованного вывода любые данные по своему усмотрению.
Подобно Django ModelForms
, ModelSerializer
также предоставляет метод create
и update
, так что вы можете создавать и обновлять экземпляры моделей через ваш сериализатор и конечные точки API.
Еще одной мощной особенностью сериализаторов Django REST Framework является то, что помимо просто обработки форм, они могут использоваться для сериализации данных в _bulk_
. Вы можете сериализовать целые наборы запросов в JSON без каких-либо модификаций.
Виды
Django REST Framework предоставляет общие представления на основе классов, которые можно просто использовать "из коробки". Эти представления будут автоматически создавать для вас как просматриваемый API, так и JSON-формат API.
Конфигурация представлений на основе классов Django REST Framework практически идентична конфигурации представлений на основе классов Django, поэтому вы должны быть в состоянии сразу разобраться с синтаксисом.
Для перечисления, создания, извлечения, уничтожения и обновления предусмотрены представления. Все они могут использоваться по отдельности как представления, основанные на классах, и подключаться к любому URL-маршруту, или же их части могут быть "смешаны" вместе, чтобы включить или исключить определенные действия или функциональность конечной точки из ваших представлений.
Однако для большинства ваших нужд Django REST Framework оказал нам услугу, объединив конечные точки, которые сочетаются друг с другом на основе спецификации REST, предоставив нам ListCreateAPIView
, RetrieveUpdateAPIView
, RetrieveDestroyAPIView
и, наконец, RetrieveUpdateDestroyAPIView
.
Для того чтобы сделать еще один шаг вперед, Django REST Framework предоставляет ViewSets
, которые представляют собой единые классы представлений, обеспечивающие всю функциональность представления для данной конечной точки. Это пять конечных точек, не говоря уже о встроенном API для просмотра, и все это бесплатно. Это великолепно.
Таким образом, если вы используете общие представления, основанные на классах Django, вы сможете создать практически идентичные представления, используя представления, основанные на классах DRF, для создания вашего API тем же способом.
Самое приятное, что все эти представления могут быть основаны на классах Django Model, так что при изменении модели данных конечные точки будут оставаться актуальными, и вам не придется их поддерживать.
Просмотровый API
Я уже несколько раз упоминал о browsable API, потому что это такой подарок. Наличие просматриваемого API может служить как документацией, так и средством поиска неисправностей и дымового тестирования API. Отсутствие необходимости писать документацию экономит массу времени.
Просмотровый API также можно настраивать, если вам не нравится стандартное форматирование или стиль создаваемых страниц. Существуют сторонние инструменты, которые привлекают большое внимание тем, что делают то же самое, что и API с возможностью просмотра; они позволяют запрашивать конечные точки API и визуализировать данные в чистом и даже красивом виде. В REST-фреймворке Django это уже реализовано!
URLs
То, как DRF работает с URL-адресами, опять же смоделировано по образцу самого Django. Когда вы добавляете представление в свой проект, вам необходимо добавить URL-маршрут для этого представления. DRF предоставляет несколько замечательных утилит для работы с комбинированными классами представлений, поэтому маршруты создаются автоматически. Используя классы провайдера Router, ваши представления будут подключаться и функционировать так, как ожидается, без особых усилий с вашей стороны
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = router.urls
Разумеется, вы можете подключать URL к представлениям точно так же, как вы подключаете представления Django к URL-маршрутам:
from django.urls import path, include
urlpatterns = [
path('<int:pk>', views.CharacterDetailView.as_view(), name='get_update_delete'),
]
Ответ и просьбы ГДРФ
Так же как и Django, Django REST Framework имеет свои собственные специальные Response
и Request
классы. Они основаны на классах Django HttpRequest
и TemplateResponse
соответственно, и переработаны для более удобного использования при работе с API и характером данных API.
Django REST Framework Response
Класс DRF Response
предоставляет атрибут .data
, который аналогичен request.POST
, но доступен даже тогда, когда POST
не используется метод запроса, и, кроме того, .data
обрабатывает произвольные данные, тогда как POST
обрабатывает только данные формы, представленные через форму в браузере.
Django REST Framework Request
Класс DRF Response
в основном такой же, как и его аналог в Django, за исключением того, что он отображает имеющееся у него содержимое на основе content-type
, используемого клиентом. Это означает, что если вы используете браузер, командную строку или программный интерфейс для взаимодействия с API, то получаемый вами ответ будет автоматически соответствовать тому, что лучше для вашего клиента. Возвращаемый content-type
будет соответствовать типу содержимого, в котором вы отправили свои данные. Однако вы также можете указать нужный вам ответ content-type
, указав расширение конечной точки при вызове, т.е. /endpoint.json
TL;DR: Давайте начнем быстро
Вы пишете приложение для фанатской фантастики о супергероях и хотите, чтобы оно могло переходить с веб-версии на мобильную. Для этого вам нужен API. API нужен уже вчера, так что давайте сделаем это как можно быстрее:
Сначала создайте сериализатор для своей модели. Он служит как для входной проверки, так и для выходной сериализации ответов API:
Использование ModelSerializer для быстрой сериализации существующей модели
Вот наш models.py с определенными моделями и отношениями:
"""
Character models
"""
import random
from django.db import models
from django.urls import reverse_lazy
from .constants import CHARACTER_TYPES, EXTRA
class Character(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
profession = models.CharField(max_length=50) # Choices later
mentor = models.ForeignKey('Character', models.DO_NOTHING, related_name='proteges', null=True, blank=True)
team = models.ForeignKey('Team', models.DO_NOTHING, null=True, blank=True)
type = models.CharField(max_length=20, choices=CHARACTER_TYPES, default=EXTRA)
def __str__(self):
return '{name} ({team_name})'.format(name=self.name, team_name=self.team.name)
@staticmethod
def get_random_line():
try:
return random.choice(Line.objects.all())
except IndexError:
return 'Say what..?'
def get_random_line_modifier(self):
try:
return random.choice(self.line_modifiers.all())
except IndexError:
return ''
def get_line(self):
return '{} {}'.format(self.get_random_line(), self.get_random_line_modifier())
def get_absolute_url(self):
return reverse_lazy('characters:detail', kwargs={'pk': self.pk})
class Team(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
def __str__(self):
return self.name
class LineModifier(models.Model):
character = models.ForeignKey('Character', models.DO_NOTHING, related_name='line_modifiers')
modifier = models.CharField(max_length=50)
def __str__(self):
return self.modifier
class Line(models.Model):
line_text = models.TextField()
def __str__(self):
return self.line_text
А единственный необходимый нам сериализатор мы рассмотрели ранее:
"""
Serializers for Character model
"""
from rest_framework import serializers
from characters.models import Character
class CharacterSerializer(serializers.ModelSerializer):
mentor = serializers.StringRelatedField()
team = serializers.StringRelatedField()
random_line = serializers.SerializerMethodField()
@staticmethod
def get_random_line(obj):
return obj.get_line()
class Meta:
model = Character
fields = (
'name', 'description', 'profession', 'mentor', 'team', 'type', 'random_line',
)
Используйте ModelViewSet
, чтобы получить представление API за считанные секунды
Для нашего приложения нам пока нужно раскрыть только модель Characters, чтобы ваше приложение с моделью могло CRUD (Create, Retrieve, Update, and Destroy) Characters. Остальные модели будут доступны только для чтения через сериализатор Characters, но мы не будем позволять людям добавлять эти модели через API.
Таким образом, наше использование ModelViewSet
выглядит следующим образом:
"""
Views for the Character API
"""
from characters.models import Character
from characters.serializers import CharacterSerializer
from rest_framework import viewsets
class CharacterViewSet(viewsets.ModelViewSet):
queryset = Character.objects.all()
serializer_class = CharacterSerializer
Да, именно так. Django REST Framework настолько мощный. Это дает нам действия List, Create, Retrieve, Update (как полное, так и частичное) и Destroy.
Опирайтесь на DefaultRouter
для быстрых маршрутов, определяемых на основе ваших ViewSet
Для того чтобы соединить все это вместе, нам нужно добавить маршрут, чтобы звонки могли направляться на наш новый ViewSet
.
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter()
router.register(r'characters', views.CharacterViewSet)
v3_patterns = [
path('', include(router.urls)),
]
Благодаря использованию класса DRF DefaultRouter
с классом ViewSet
, все маршруты создаются автоматически, HTTP-версии обрабатываются соответствующим образом, и даже переключение типов содержимого работает без дополнительной настройки. Из доступного для просмотра API мы можем подтвердить, что json выглядит так, как мы ожидали, GET
, PUT
, PATCH
и DELETE
существуют и работают так, как ожидалось. Просто волшебно, как много полезного мы получаем от использования встроенных классов DRF. DRF настолько всеобъемлющ и соответствует спецификации RESTful, что вы знаете, что ваши пользователи получат то, что они ожидают.
Собираем все воедино
Вот как все выглядит после того, как вы соединили части вместе.
У нас есть конечная точка для перечисления и создания символов:
Затем у нас есть конечная точка для просмотра деталей одного персонажа, а также для обновления и удаления этого персонажа:
Все эти конечные точки принимают вызов OPTIONS для получения информации о том, что может быть представлено.
Почти все, что вы здесь видите, было создано с помощью Django REST Framework. Формы, красивое форматирование и навигация - все это просто часть работы DRF. Единственное, что мы сделали, это подключили маршрут и добавили некоторые данные!
Заключение
Фреймворк Django REST Framework является довольно удивительным. API почти всегда требуются в современных приложениях в связи с развитием мобильных устройств. Все, что вы создаете, с первого дня будет получать запросы на создание нативного мобильного приложения.
Теперь, используя DRF, вы можете предоставить API к своим данным и начать создавать мобильное приложение в течение нескольких минут. Все API будут генерироваться на основе существующей модели данных, так что по мере развития ваших моделей будет развиваться и API.
То, что мы рассмотрели здесь сегодня, является лишь вершиной айсберга, когда речь идет о функциональности, которую предоставляет Django REST Framework.
DRF также обеспечивает аутентификацию, дросселирование конечных точек, версионирование, пагинацию и кэширование - вот лишь несколько важных элементов, о которых следует помнить при создании веб-приложений.
Как и в случае с Django, существует множество сторонних, хорошо поддерживаемых плагинов к DRF, которые помогут вам сэкономить время и головную боль, связанные с изобретением колеса.
Вернуться на верх