Django REST Framework поставляется с набором типовых представлений и миксинов, которые можно использовать для разработки представлений API. Они предоставляют функциональность извлечения, создания, обновления или удаления модельных объектов. Все типовые поставляемые с фреймворком REST миксинные классы и представления находятся по адресу https://www.django-rest-framework.org/api-guide/generic-views/.
APIView
Класс APIView обеспечивает обычно требуемое поведение для стандартных представлений списка и сведений. С классом APIView мы можем переписать корневое представление как представление на основе классов. Они предоставляют методы действий, такие как get(), post(), put(), patch() и delete(), а не определяют методы обработчика.
Создание представлений с помощью APIView
Давайте посмотрим, как создавать представления с помощью APIView.
Добавим в файл views.py приложения blog_api, следующий код:
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from blog.models import Post
from .serializers import PostSerializer
class PostList(APIView):
def get(self, request, format=None):
posts = Post.objects.all()
serializer = PostSerializer(posts, many=True)
return Response(serializer.data)
def post(self, request, format=None):
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)
Помимо методов get() и post() можно прописывать и другие для обработки соответствующих типов запросов:
get()– вызывается при GET-запросах;post()– вызывается при POST-запросах;put()– вызывается при PUT-запросах;patch()– вызывается при PATCH-запросах;delete()– вызывается при DELETE-запросах.
Рассмотрим их при создании детального отображения постов, добавим в файл views.py приложения blog_api, следующий код:
class PostDetail(APIView):
def get_object(self, pk):
try:
return Post.objects.get(pk=pk)
except Post.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
post = self.get_object(pk)
serializer = PostSerializer(post)
return Response(serializer.data)
def put(self, request, pk, format=None):
post = self.get_object(pk)
serializer = PostSerializer(post, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def patch(self, request, pk, format=None):
post = self.get_object(pk)
serializer = PostSerializer(post,
data=request.data,
partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
queryset = self.get_object(pk)
queryset.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Давайте проверим работу, для этого перейдем по адресу http://127.0.0.1:8000/api/:
Давайте попробуем создать новую запись, для этого опустимся в самый низ страницы и введем тестовую запись:
После нажатия кнопки POST мы видим успешное выполнение данной операции, а именно функции post в классе PostList:
Мы видим успешный ответ сервера HTTP 201 Created, и нашу запись.
Вернемся на главную страницу нашего API http://127.0.0.1:8000/api/ и проверим наш список постов:
Далее давайте перейдем к просмотру нашей записи через API, в моем случае у записи id=6, поэтому перейдем по адресу http://127.0.0.1:8000/api/6/.
На скриншоте выше мы видим что у нас есть кнопки PUT, PATCH и DELETE. Это именно те функции которые мы добавили в нашем представлении PostDetail.
У вас здесь может возникнуть вопрос, а как одно и то же представление для одного и того же URL-адреса «понимает», какой из методов следует вызывать, когда приходит какой-либо запрос от клиента? В действительности, все просто. Когда клиент формирует запрос, то в его заголовке прописывается тип этого запроса: GET, POST, DELETE, PUT и т.п. Затем, алгоритм, заложенный в представления DRF автоматически вызывает метод, связанный с поступившим запросом. Если нужный метод не находится, то клиенту возвращается JSON-строка с сообщением, что метод не разрешен.