View-классы

Знакомство со view-классами Django REST Framework начнём с низкоуровневого APIView из модуля rest_framework.views.
Как и его класс-родитель View, класс APIView при получении запроса вызывает пустой метод. При получении GET-запроса будет вызван метод get(), при получении POST-запроса — метод post(), но эти методы не выполняют никаких действий, их функциональность нужно описывать самостоятельно. В целом этот класс работает так же, как и view-функции:
Скопировать кодPYTHON
class APIPost(APIView): # переопределим родительский метод get(), всё равно он был пустой и ничего не умел def get(self, request): posts = Post.objects.all() serializer = PostSerializer(posts, many=True) return Response(serializer.data) # переопределим родительский метод post(), с ним та же история, что и с get() 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, которые выполняют только одно действие:
Работа с ними аналогична работе с комбинированными view-классами модуля rest_framework.generics.