В уроке 10 по созданию API на Django REST Framework, мы рассмотрим, что такое ViewSets и Routers, зачем они применяются, и как их использовать.
В предыдущем уроке мы рассмотрели аутентификацию по токену: Django REST Framework создание API: Урок 9, аутентификация по токену
В одном из уроков, мы создавали большое представление, которое содержало в себе все возможности: Django REST Framework создание API: Урок 6, миксины для представлений
Что такое ViewSet?
ViewSet - это набор связанных представлений, в котором предоставлены обработчики действий, например: .list()
, .create()
, .retrieve()
, .update()
Давайте рассмотрим пример создания ViewSet.
Для этого, в модуле blog я создам файл viewsets.py со следующим содержимым:
modules/blog/viewsets.py
from rest_framework import viewsets
from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
lookup_field = 'slug'
Пояснение:
- viewsets импортируем из rest_framework
- Создаем класс
ArticleViewSet
наследуясь отModelViewSet
- Добавляем
queryset
,serializer_class
- Добавляем
lookup_field
для операций retreieve, destroy, update
Что такое Routers?
Routers - это маршрутизатор для контроллера, в нашем случае, как пример, контроллером послужит выше написанный ArticleViewSet
. С помощью маршрутизатора мы получим необходимые пути для управления экземпляром, вместо того, чтобы объявлять каждый маршрут отдельно в urls.py.
Теперь создадим файл routers.py в модуле blog со следующим содержимым:
modules/blog/routers.py
from rest_framework.routers import DefaultRouter
from modules.blog.viewsets import ArticleViewSet
router = DefaultRouter()
router.register(prefix='articles', viewset=ArticleViewSet, basename='articles')
urlpatterns = router.urls
Пояснение:
- Импортируем DefaultRouter из rest_framework.routers
- В
router.register()
передаем следующие параметры:prefix
- наш путь, в нашем случае это будет что-то вродеsite/api/v2/articles/
, можно делать такой, какой вы захотите.viewset
- наше представлениеArticleViewSet
basename
- базовое имя для представлений, т.е если мы захотим получить путь детальное статьи, то это будетarticles_detail
Теперь подключим наш routers.py в главный urls.py
engine/urls.py
"""engine URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('modules.blog.urls')),
path('api/auth/', obtain_auth_token),
path('api/v2/', include('modules.blog.routers')),
]
Пояснение:
- Подключил
path('api/v2/', include('modules.blog.routers'))
Давайте теперь рассмотрим результат работы ViewSets и Routers.
Перейдем на страницу: http://127.0.0.1:8000/api/v2/articles/ и получим список всех статей с возможностью добавления статьи:


Перейдем на детальную страницу статьи: http://127.0.0.1:8000/api/v2/articles/articlelistcreateapiview-is-work/ и получим доступ к одному экземпляру по slug, а также операции обновления, удаления.


Как видите, ViewSets и Routers заменяют написание большого количества кода, но тут уже, выбор каждого, как ему поступать. У вас также доступны методы внутри ViewSets, которые позволяют при создании или обновлении вызывать дополнительные параметры и регулировать их так, как вам необходимо.
Вы также можете задавать права доступа, например следующим образом:
from rest_framework import viewsets
from rest_framework import permissions
from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
lookup_field = 'slug'
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
def get_permissions(self):
"""
Создает экземпляр и возвращает список разрешений, которые требуются этому представлению.
"""
if self.action == 'list':
permission_classes = [permissions.IsAuthenticated]
else:
permission_classes = [permissions.IsAdminUser]
return [permission() for permission in permission_classes]
Более подробно изучить ViewSet вы можете в официальной документации: Viewsets - Django REST framework