Django REST Framework создание API: Урок 6, миксины для представлений
avatar
7 | (offline)
❤️‍🔥Notehunter Developer
Добавлено:
Категория: Руководства «Django»
Комментариев: 0

В уроке 6 по созданию API на Django REST Framework, мы рассмотрим миксины DRF, они необходимы для создания гибкости в представлениях Django.

В прошлом уроке мы рассмотрели расширенные CRUD запросы: Django REST Framework создание API: Урок 5, расширенные CRUD запросы на основе классов

А теперь приступим к написанию универсального представления с помощью миксирования:

modules/blog/views/articles.py

from rest_framework import generics

class ArticleMixinView(generics.GenericAPIView):
    pass

Если мы рассмотрим класс GenericAPIView, то увидим следующие параметры:

  • queryset - набор запросов, из которого мы будем возвращать данные для просмотра.
  • serializer_class - класс сериализатора, который мы будем использовать для проверки и десериализации входных данных.
  • lookup_field - поле, по которому мы будем находить один экземпляр модели.
  • lookup_url_kwarg - аргумент ключевого слова URL, который следует использовать для поиска объекта, использует тот же, что lookup_field.
  • pagination_class - класс разбивки результатов на страницы, рассмотрим в последующих уроках.
  • filter_backends - список классов фильтров сервера, для фильтрации набора запросов.

Есть также и базовые методы:

  • get_queryset()
  • get_object()
  • get_serializer_class()
  • filter_queryset()

Микширование:

Добавим ListModelMixin для метода get() , данный метод позволяет нам получить список, например статей, поэтому заполним также и параметры

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics, mixins


class ArticleMixinView(generics.GenericAPIView, mixins.ListModelMixin):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

    def get(self, request, *args, **kwargs):
        # HTTP -> GET метод
        # self.list из ListModelMixin
        return self.list(request, *args, **kwargs)

Пояснение:

  • self.list мы берем для списка получаемых экземпляров, получаемых из queryset с помощью: ListModelMixin

Давайте попробуем испытать данное представление.

Необязательно для тех, кто делает все в файле views.py. 

Добавлю импорты в __init__.py:

from modules.blog.views.articles import ArticleMixinView

__all__ = '__all__'

И добавлю обработку нашего представления в urls.py:

modules/blog/urls.py

from django.urls import path
from modules.blog import views

urlpatterns = [
    path('articles/', views.ArticleMixinView.as_view(), name='api_articles_list'),
]

Попробуем отправить GET и POST запрос на получение списка статей по ссылке: http://127.0.0.1:8000/api/articles/

С помощью микширования мы можем поменять, чтобы POST запрос работал и получал список: 

class ArticleMixinView(generics.GenericAPIView, mixins.ListModelMixin):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

    def post(self, request, *args, **kwargs):
        # HTTP -> POST метод
        # self.list из ListModelMixin
        return self.list(request, *args, **kwargs)

И проверяем:

Как видите, мы получили список с помощью POST запроса. Но в этот раз у нас не работает GET запрос. Давайте пойдем дальше и дополним метод get():

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics, mixins


class ArticleMixinView(generics.GenericAPIView, mixins.ListModelMixin, mixins.RetrieveModelMixin):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = 'slug'

    def get(self, request, *args, **kwargs):
        # HTTP -> GET метод
        print(args, kwargs)
        # Если мы передали slug в url, то получаем его из параметров
        slug = kwargs.get('slug')
        # И если slug существует, возвращаем один экземпляр
        if slug is not None:
            # self.retrieve из RetrieveModelMixin
            return self.retrieve(request, *args, **kwargs)
        # self.list из ListModelMixin
        return self.list(request, *args, **kwargs)

Пояснение:

  • self.retrieve мы берем для единичного экземпляра, который хотим получить с помощью заданного slug, все это работает с миксином: RetrieveModelMixin
  • Выводимые данные в процессе отработки представления print(args, kwargs): >>> () {'slug': 'test-article-4'}

Добавим обработку представления в urls.py:

modules/blog/urls.py

from django.urls import path
from modules.blog import views

urlpatterns = [
    path('articles/', views.ArticleMixinView.as_view(), name='api_articles_list'),
    path('articles/<str:slug>/', views.ArticleMixinView.as_view(), name='api_articles_detail')
]

Проверим GET запрос отправив его на страницу, например: http://127.0.0.1:8000/api/articles/test-article-4/

Отлично, все работает. Также у нас остается возможность по этому же представлению обратиться к списку статей.

Давайте дополним наше представление возможностью добавлять статьи:

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics, mixins


class ArticleMixinView(generics.GenericAPIView, mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = 'slug'

    def get(self, request, *args, **kwargs):
        # HTTP -> GET метод
        print(args, kwargs)
        # Если мы передали slug в url, то получаем его из параметров
        slug = kwargs.get('slug')
        # И если slug существует, возвращаем один экземпляр
        if slug is not None:
            # self.retrieve из RetrieveModelMixin
            return self.retrieve(request, *args, **kwargs)
        # self.list из ListModelMixin
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        # HTTP -> POST метод
        # self.create из CreateModelMixin
        return self.create(request, *args, **kwargs)

Пояснение:

  • self.create мы берем для создания экземпляра с помощью: CreateModelMixin
  • Также нам доступен метод вызываем при добавлении экземпляра с помощью CreateModelMixin:
    • perform_create(self, serializer)

Попробуем отправить POST запрос с данными новой статьи по ссылке: http://127.0.0.1:8000/api/articles/

Отправляемые JSON данные:

{
	"title": "Тестовая статья номер 5",
	"slug": "test-article-5",
	"short_description": "Краткое описание статьи 5",
	"full_description": "Полное описание статьи 5",
	"category": 1
}

Смотрим результат:

Как видите, статью мы добавили. Пойдем дальше и добавим больше методов в наше универсальное представление:

Добавим возможность обновления статьи:

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics, mixins


class ArticleMixinView(generics.GenericAPIView, mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = 'slug'

    def get(self, request, *args, **kwargs):
        # HTTP -> GET метод
        print(args, kwargs)
        # Если мы передали slug в url, то получаем его из параметров
        slug = kwargs.get('slug')
        # И если slug существует, возвращаем один экземпляр
        if slug is not None:
            # self.retrieve из RetrieveModelMixin
            return self.retrieve(request, *args, **kwargs)
        # self.list из ListModelMixin
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        # HTTP -> POST метод
        # self.create из CreateModelMixin
        return self.create(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        # HTTP -> PUT метод
        # self.update из UpdateModelMixin
        return self.update(request, *args, **kwargs)
    
    def patch(self, request, *args, **kwargs):
        # HTTP -> PATCH метод
        # self.partial_update из UpdateModelMixin
        return self.partial_update(request, *args, **kwargs)

Пояснение:

  • self.update и self.partial_update мы берем для обновления экземпляра с помощью: UpdateModelMixin
  • Также нам доступен метод вызываем при обновления экземпляра с помощью UpdateModelMixin:
    • perform_update(self, serializer)

Попробуем обновить статью, отправив запрос PUT на страницу: http://127.0.0.1:8000/api/articles/test-article-5/

Отлично, и как завершающий этот урок, мы добавим миксин для удаления экземпляра:

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics, mixins


class ArticleMixinView(
    generics.GenericAPIView, 
    mixins.ListModelMixin, 
    mixins.RetrieveModelMixin, 
    mixins.CreateModelMixin, 
    mixins.UpdateModelMixin,
    mixins.DestroyModelMixin):

    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = 'slug'

    def get(self, request, *args, **kwargs):
        # HTTP -> GET метод
        print(args, kwargs)
        # Если мы передали slug в url, то получаем его из параметров
        slug = kwargs.get('slug')
        # И если slug существует, возвращаем один экземпляр
        if slug is not None:
            # self.retrieve из RetrieveModelMixin
            return self.retrieve(request, *args, **kwargs)
        # self.list из ListModelMixin
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        # HTTP -> POST метод
        # self.create из CreateModelMixin
        return self.create(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        # HTTP -> PUT метод
        # self.update из UpdateModelMixin
        return self.update(request, *args, **kwargs)
    
    def patch(self, request, *args, **kwargs):
        # HTTP -> PATCH метод
        # self.partial_update из UpdateModelMixin
        return self.partial_update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        # HTTP -> DELETE метод
        # self.delete из DestroyModelMixin
        return self.destroy(request, *args, **kwargs)

Пояснение:

  • self.destroy мы берем для удаления экземпляра с помощью: DestroyModelMixin 
  • Также нам доступен метод вызываем при удалении экземпляра с помощью DestroyModelMixin:
    • perform_destroy(self, instance)

Попробуем удалить статью, отправив запрос DELETE на страницу: http://127.0.0.1:8000/api/articles/test-article-5/

Отлично, как видите, статья была удалена. Все это с помощью одного представления созданного с помощью миксинов, а также обращения с различными запросами: GET, POST, PUT, DELETE

Теги записи: Django, Django REST Framework, API, DRF,
Комментарии к статье 0
Комментариев нет
Форма добавления комментария (необходима регистрация)