Создание Django API используя Django Rest Framework часть 3
Это третья часть из серии статей про Django API. Первая часть находится здесь. Вторая здесь. В этой статье мы рассмотрим использование наборы представлений класс viewsets от Django REST Framework. Основное отличие viewsets от GenericAPIView и APIView, в том что это еще один дополнительный абстрагирующий класс, который с одной стороны позволяет уменьшить базовый код а с другой имеет большие возможности по кастомизации и расширению.
И так начнем, с изменений в файле представления. Используем базовый класс viewsets.ViewSet унаследуем от него наш класс ArticleView и определим методы получения всех статей (list) и одну выбранную статью (retrieve). Для этого внесем следующие изменения в article/views.py:
from django.shortcuts import get_object_or_404 from rest_framework import viewsets from rest_framework.response import Response from .models import Article from .serializers import ArticleSerializer class ArticleView(viewsets.ViewSet): """ A simple ViewSet that for listing or retrieving users. """ def list(self, request): queryset = Article.objects.all() serializer = ArticleSerializer(queryset, many=True) return Response(serializer.data) def retrieve(self, request, pk=None): queryset = Article.objects.all() user = get_object_or_404(queryset, pk=pk) serializer = ArticleSerializer(user) return Response(serializer.data)
Далее нам нужно связать наши методы list и retrieve с URL API. Для этого внесите изменения в article/urls.py:
from django.urls import path from .views import ArticleView app_name = "articles" # app_name will help us do a reverse look-up latter. urlpatterns = [ path('articles/', ArticleView.as_view({'get': 'list'})), path('articles/<int:pk>', ArticleView.as_view({'get': 'retrieve'})), ]
Если теперь обратится по URL: http://127.0.0.1:8000/api/articles/ или http://127.0.0.1:8000/api/articles/1/ то должно все работать как раньше.
Теперь воспользуется новым для нас классом роутера DRF DefaultRouter. Этот класс позволяет значительно уменьшить код в URL. Зарегистрируем наш класс ArticleView в этом классе и позволяем ему теперь автоматически генерировать обработчики url. Удалите весь старый код из article/urls.py и внесите следующие изменения в этот файл:
from rest_framework.routers import DefaultRouter from .views import ArticleView router = DefaultRouter() router.register(r'articles', ArticleView, basename='user') urlpatterns = router.urls
Теперь если обратится по URL: http://127.0.0.1:8000/api/articles/ или http://127.0.0.1:8000/api/articles/1/ то опять все должно работать как раньше. Но обратите внимание мы реализовали только два метода API получения списка статей и получение одной выбранной статье.
Что бы реализовать методы создания, редактирования и удаления мы можем определить эти методы вручную или воспользоваться классом viewsets.ModelViewSet в котором уже все сделано за нас. Внесите следующие изменения в файл article/views.py:
from rest_framework import viewsets from .models import Article from .serializers import ArticleSerializer class ArticleViewSet(viewsets.ModelViewSet): serializer_class = ArticleSerializer queryset = Article.objects.all()
И соотвествующие изменения в файл article/urls.py
from rest_framework.routers import DefaultRouter from .views import ArticleViewSet router = DefaultRouter() router.register(r'articles', ArticleViewSet, basename='user') urlpatterns = router.urls
Теперь мы можем создавать, редактировать и удалять
Используя viewsets мы буквально в пару строк получили полностью рабочий CRUD для выбранной таблицы.
На этом я пожалуй хотел завершить эту статью. В этой серии статей мы очень кратко рассмотрели и сравнили возможности классов DRF APIView, GenericAPIView, ViewSets для создания CRUD. На самом деле у этих классов гораздо больше возможностей и особенностей их применения и если вы захотите изучить их глубже обратитесь к официальной документации DRF.
Благодарю за перевод!
Пропущено слово с «другой» между «с» и «имеет»:
» который с одной стороны позволяет уменьшить базовый код а с имеет большие возможности»
Спасибо за правку.
Поскольку при создании новой записи вы не указываете\выбираете автора, будет выпадать ошибка о том, что author_id не может быть NULL.
Для правильной работы в serializer нужно добавить:
def create(self, validated_data):
validated_data[‘author_id’] = your_author_id
return super(ArticleSerializer, self).create(validated_data)
для неявного указания автора.
Достаточно разместить в ArticleViewSet функцию perform_create из предыдущей статьи.
basename=’user’ — тут выглядит немного странно и сбивает с толку. Это недосмотр или всё корректно?
Вы правы, автор статьи немного недосмотрел
но почему во всех подобных статьях старательно игнорируют загрузку файлов?
Панимаю,уже второй день найти не могу
При редактировании через Postman показывает код страницы 500. Почему именно с редактированием ошибка? С удалением, получением и созданием статей проблем нет