Создание Django API используя Django Rest Framework часть 3

Spread the love

Это третья часть из серии статей про 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.

Была ли вам полезна эта статья?
[47 / 4.7]

Spread the love
Подписаться
Уведомление о
guest
9 Комментарий
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Андрей
Андрей
2 лет назад

Благодарю за перевод!

Пропущено слово с «другой» между «с» и «имеет»:
» который с одной стороны позволяет уменьшить базовый код а с имеет большие возможности»

Никита
Никита
1 год назад

Поскольку при создании новой записи вы не указываете\выбираете автора, будет выпадать ошибка о том, что author_id не может быть NULL.

Для правильной работы в serializer нужно добавить:
def create(self, validated_data):
validated_data[‘author_id’] = your_author_id
return super(ArticleSerializer, self).create(validated_data)
для неявного указания автора.

Иван
Иван
1 год назад
Reply to  Никита

Достаточно разместить в ArticleViewSet функцию perform_create из предыдущей статьи.

iLq
iLq
1 год назад

basename=’user’ — тут выглядит немного странно и сбивает с толку. Это недосмотр или всё корректно?

edteam
Администратор
edteam(@edteam)
1 год назад
Reply to  iLq

Вы правы, автор статьи немного недосмотрел

Анонимно
Анонимно
1 год назад

но почему во всех подобных статьях старательно игнорируют загрузку файлов?

Дмитрий
Дмитрий
11 месяцев назад

Панимаю,уже второй день найти не могу

Анонимно
Анонимно
20 дней назад

При редактировании через Postman показывает код страницы 500. Почему именно с редактированием ошибка? С удалением, получением и созданием статей проблем нет

9
0
Будем рады вашим мыслям, пожалуйста, прокомментируйте.x
()
x