Python

Создание 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.

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

Spread the love
Editorial Team

View Comments

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

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

  • Поскольку при создании новой записи вы не указываете\выбираете автора, будет выпадать ошибка о том, что 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. Почему именно с редактированием ошибка? С удалением, получением и созданием статей проблем нет

Recent Posts

Vue 3.4 Новая механика v-model компонента

Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование​ v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…

11 месяцев ago

Анонс Vue 3.4

Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…

11 месяцев ago

Как принудительно пере-отобразить (re-render) компонент Vue

Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…

2 года ago

Проблемы с установкой сертификата на nginix

Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…

2 года ago

Введение в JavaScript Temporal API

Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…

2 года ago

Когда и как выбирать между медиа запросами и контейнерными запросами

Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…

2 года ago