View-классы
Знакомство со view-классами Django REST Framework начнём с низкоуровневого APIView
из модуля rest_framework.views
.
Как и его класс-родитель View
, класс APIView
при получении запроса вызывает пустой метод. При получении GET-запроса будет вызван метод get()
, при получении POST-запроса — метод post()
, но эти методы не выполняют никаких действий, их функциональность нужно описывать самостоятельно. В целом этот класс работает так же, как и view-функции:
Скопировать кодPYTHON
class APIPost(APIView):
def get(self, request):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(serializer.data)
def post(self, request):
serializer = PostSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Как вы заметили, код ничем не отличается от того, что был во view-функции, только он описан в объектно-ориентированном стиле.
Низкоуровневые view-классы нужны для решения специфических задач, описав с нуля всю логику (в низкоуровневых классах логика по умолчанию не предустановлена).
При типовых действиях (вывод списка объектов или запрос объекта по id) удобнее использовать высокоуровневые view-классы, «дженерики» (Generic Views): в них уже реализованы все механизмы, необходимые для решения задачи.
Некоторые из них выполняют строго определённую задачу, а некоторые более универсальны и могут «переключаться» на разные задачи в зависимости от HTTP-метода, которым был отправлен запрос.
В дженериках задают два поля:
queryset
(набор записей, который будет обрабатываться) и
serializer_class
(сериалайзер, который будет преобразовывать объекты в формат JSON). В DRF все
Generic Views объединены в модуле
rest_framework.generics. Полный список можно посмотреть
здесь, в документации по django rest framework.
Рассмотрим для примера класс ListCreateAPIView
: он отображает всю коллекцию (все посты) или может создать новую запись в модели (новый пост в модели Post, например).
А для того, чтобы просматривать, обновлять или удалять записи по одной — применим дженерик-класс RetrieveUpdateDestroyAPIView
.
Опишем их в коде:
Скопировать кодPYTHON
from rest_framework import generics
from .models import Post
from .serializers import PostSerializers
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
Работа с DRF отличается от знакомой вам структуры только сериализацией (файл serializers.py) и отсутствием работы с шаблонами. Мы сделали API для Yatube при минимальном количестве изменений в коде!
Удобная шпаргалка по классам DRF:
http://www.cdrf.co/ Добавьте эту страницу в закладки и заглядывайте туда регулярно: с каждым разом этот справочник будет становиться всё понятнее и полезнее.
В примере кода мы унаследовались от комбинированных view-классов: их удобнее применить к решению нашей задачи. Но иногда они бывают избыточны и требуется view-класс, выполняющий только одно действие. Например, при создании API «только для чтения» (как знакомый вам StarWarsAPI) лучше подключить ListAPIView
, который выполняет ровно одно действие: выводит список объектов в ответ на метод GET.
Вот остальные view-классы DRF, которые выполняют только одно действие:
RetrieveAPIView
— выводит один объект (метод GET)CreateAPIView
— создает новый объект (метод POST)UpdateAPIView
— редактирует объект (методы PUT и PATCH)DestroyAPIView
— удаляет объект (метод DELETE)
Работа с ними аналогична работе с комбинированными view-классами модуля rest_framework.generics.