Viewsets
ViewSets
После того, как маршрутизация определила, какой контроллер использовать для запроса, ваш контроллер отвечает за осмысление запроса и создание соответствующего вывода.
DRF позволяет объединить логику для набора связанных представлений в одном классе, называемом ViewSet. В других фреймворках вы также можете встретить концептуально схожие реализации с названиями типа "Ресурсы" или "Контроллеры".
Класс ViewSet - это просто тип представления на основе класса, который не предоставляет никаких обработчиков методов, таких как .get() или .post(), а вместо этого предоставляет такие действия, как .list() и .create().
Обработчики методов для ViewSet привязываются к соответствующим действиям только в момент финализации представления с помощью метода .as_view().
Обычно вместо того, чтобы явно регистрировать представления в наборе представлений в urlconf, вы регистрируете набор представлений в классе маршрутизатора, который автоматически определяет urlconf для вас.
Пример
Давайте определим простой набор представлений, который можно использовать для получения списка всех пользователей в системе или конкретного пользователя.
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404
from myapps.serializers import UserSerializer
from rest_framework import viewsets
from rest_framework.response import Response
class UserViewSet(viewsets.ViewSet):
"""
A simple ViewSet for listing or retrieving users.
"""
def list(self, request):
queryset = User.objects.all()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
queryset = User.objects.all()
user = get_object_or_404(queryset, pk=pk)
serializer = UserSerializer(user)
return Response(serializer.data)Если нужно, мы можем разделить этот набор представлений на два отдельных представления, как показано ниже:
Обычно мы не делаем этого, а регистрируем набор представлений в маршрутизаторе и позволяем автоматически генерировать urlconf.
Вместо того чтобы писать свои собственные наборы представлений, вы часто захотите использовать существующие базовые классы, которые предоставляют набор поведения по умолчанию. Например:
Есть два основных преимущества использования класса ViewSet вместо класса View.
Повторяющаяся логика может быть объединена в один класс. В приведенном выше примере нам нужно указать
querysetтолько один раз, и он будет использоваться в нескольких представлениях.Используя маршрутизаторы, нам больше не нужно самим создавать URL conf.
Оба варианта имеют свои преимущества. Использование обычных представлений и URL-конфигураций является более явным и дает вам больше контроля. Наборы представлений полезны, если вы хотите быстро приступить к работе, или если у вас большой API и вы хотите обеспечить последовательную конфигурацию URL во всем.
Действия ViewSet
Маршрутизаторы по умолчанию, входящие в состав DRF, обеспечивают маршруты для стандартного набора действий в стиле create/retrieve/update/destroy, как показано ниже:
Интроспекция действий ViewSet
Во время диспетчеризации для ViewSet доступны следующие атрибуты.
basename- основа, используемая для имен создаваемых URL.action- имя текущего действия (например,list,create).detail- булево значение, указывающее, настроено ли текущее действие на просмотр списка или деталей.suffix- суффикс отображения для типа набора представлений - зеркально отражает атрибутdetail.name- отображаемое имя набора представлений. Этот аргумент является взаимоисключающим дляsuffix.description- отображаемое описание для отдельного вида набора представлений.
Вы можете использовать эти атрибуты для настройки поведения в зависимости от текущего действия. Например, вы можете ограничить права на все действия, кроме действия list, следующим образом:
Добавление дополнительных действий в маршрутизацию
Если у вас есть специальные методы, которые должны быть маршрутизируемыми, вы можете пометить их как таковые с помощью декоратора @action. Как и обычные действия, дополнительные действия могут быть предназначены как для одного объекта, так и для целой коллекции. Чтобы указать это, установите аргумент detail в True или False. Маршрутизатор настроит свои шаблоны URL соответствующим образом. Например, DefaultRouter настроит подробные действия так, чтобы они содержали pk в своих шаблонах URL.
Более полный пример дополнительных действий:
Декоратор action по умолчанию направляет запросы GET, но может принимать и другие HTTP-методы, задав аргумент methods. Например:
Аргумент methods также поддерживает методы HTTP, определенные как HTTPMethod. Пример ниже идентичен приведенному выше:
Декоратор позволяет переопределить любую конфигурацию на уровне набора представлений, такую как permission_classes, serializer_class, filter_backends...:
Два новых действия будут доступны по адресам ^users/{pk}/set_password/$ и ^users/{pk}/unset_password/$. Используйте параметры url_path и url_name для изменения сегмента URL и обратного имени URL действия.
Чтобы просмотреть все дополнительные действия, вызовите метод .get_extra_actions().
Маршрутизация дополнительных методов HTTP для дополнительных действий
Дополнительные действия могут сопоставлять дополнительные HTTP-методы с отдельными методами ViewSet. Например, описанные выше методы установки и снятия пароля могут быть объединены в один маршрут. Обратите внимание, что дополнительные сопоставления не принимают аргументов.
Получение URL-адреса действия
Если вам нужно получить URL-адрес действия, используйте метод .reverse_action(). Это удобная обертка для reverse(), автоматически передающая объект request представления и дополняющая url_name атрибутом .basename.
Обратите внимание, что basename предоставляется маршрутизатором во время регистрации ViewSet. Если вы не используете маршрутизатор, то вы должны предоставить аргумент basename методу .as_view().
Используя пример из предыдущего раздела:
В качестве альтернативы можно использовать атрибут url_name, установленный декоратором @action.
Аргумент url_name для .reverse_action() должен совпадать с тем же аргументом декоратора @action. Кроме того, этот метод можно использовать для отмены действий по умолчанию, таких как list и create.
API Reference
ViewSet
Класс ViewSet наследуется от APIView. Вы можете использовать любые стандартные атрибуты, такие как permission_classes, authentication_classes, чтобы управлять политикой API для набора представлений.
Класс ViewSet не предоставляет никаких реализаций действий. Чтобы использовать класс ViewSet, вам нужно переопределить его и явно определить реализацию действий.
GenericViewSet
Класс GenericViewSet наследуется от GenericAPIView и предоставляет стандартный набор методов get_object, get_queryset и другие базовые поведения общих представлений, но по умолчанию не включает никаких действий.
Чтобы использовать класс GenericViewSet, вы должны переопределить его и либо смешать необходимые классы mixin, либо явно определить реализацию действий.
ModelViewSet
Класс ModelViewSet наследуется от GenericAPIView и включает в себя реализации различных действий, смешивая поведение различных классов-миксинов.
Класс ModelViewSet предоставляет следующие действия: .list(), .retrieve(), .create(), .update(), .partial_update() и .destroy().
Пример
Поскольку ModelViewSet расширяет GenericAPIView, вам обычно нужно предоставить как минимум атрибуты queryset и serializer_class. Например:
Обратите внимание, что вы можете использовать любой из стандартных атрибутов или переопределений методов, предоставляемых GenericAPIView. Например, чтобы использовать ViewSet, который динамически определяет набор запросов, с которым он должен работать, вы можете сделать что-то вроде этого:
Однако обратите внимание, что, после удаления свойства queryset из вашего ViewSet, любой связанный с ним router не сможет автоматически вывести базовое имя вашей Модели, поэтому вам придется указать именованный аргумент basename как часть вашей регистрации router.
Также обратите внимание, что хотя этот класс по умолчанию предоставляет полный набор действий create/list/retrieve/update/destroy, вы можете ограничить доступные операции с помощью стандартных классов разрешений.
ReadOnlyModelViewSet
Класс ReadOnlyModelViewSet также наследуется от GenericAPIView. Как и ModelViewSet, он также включает реализации различных действий, но в отличие от ModelViewSet предоставляет только действия "только для чтения", .list() и .retrieve().
Пример
Как и в случае с ModelViewSet, обычно вам нужно предоставить как минимум атрибуты queryset и serializer_class. Например:
Как и в случае с ModelViewSet, вы можете использовать любые стандартные атрибуты и переопределения методов, доступные для GenericAPIView.
Пользовательские базовые классы ViewSet
Вам может понадобиться предоставить пользовательские классы ViewSet, которые не имеют полного набора действий ModelViewSet или настраивают поведение каким-либо другим способом.
Пример
Чтобы создать базовый класс набора представлений, обеспечивающий операции create, list и retrieve, наследуйте от GenericViewSet и добавьте необходимые действия:
Создавая собственные базовые классы ViewSet, вы можете обеспечить общее поведение, которое может быть повторно использовано в нескольких наборах представлений в вашем API.
Last updated
Was this helpful?