Viewsets
Last updated
Was this helpful?
Last updated
Was this helpful?
После того, как маршрутизация определила, какой контроллер использовать для запроса, ваш контроллер отвечает за осмысление запроса и создание соответствующего вывода.
—
DRF позволяет объединить логику для набора связанных представлений в одном классе, называемом ViewSet
. В других фреймворках вы также можете встретить концептуально схожие реализации с названиями типа "Ресурсы" или "Контроллеры".
Класс ViewSet
- это просто тип представления на основе класса, который не предоставляет никаких обработчиков методов, таких как .get()
или .post()
, а вместо этого предоставляет такие действия, как .list()
и .create()
.
Обработчики методов для ViewSet
привязываются к соответствующим действиям только в момент финализации представления с помощью метода .as_view()
.
Обычно вместо того, чтобы явно регистрировать представления в наборе представлений в urlconf, вы регистрируете набор представлений в классе маршрутизатора, который автоматически определяет urlconf для вас.
Давайте определим простой набор представлений, который можно использовать для получения списка всех пользователей в системе или конкретного пользователя.
Если нужно, мы можем разделить этот набор представлений на два отдельных представления, как показано ниже:
Обычно мы не делаем этого, а регистрируем набор представлений в маршрутизаторе и позволяем автоматически генерировать urlconf.
Вместо того чтобы писать свои собственные наборы представлений, вы часто захотите использовать существующие базовые классы, которые предоставляют набор поведения по умолчанию. Например:
Есть два основных преимущества использования класса ViewSet
вместо класса View
.
Повторяющаяся логика может быть объединена в один класс. В приведенном выше примере нам нужно указать queryset
только один раз, и он будет использоваться в нескольких представлениях.
Используя маршрутизаторы, нам больше не нужно самим создавать URL conf.
Оба варианта имеют свои преимущества. Использование обычных представлений и URL-конфигураций является более явным и дает вам больше контроля. Наборы представлений полезны, если вы хотите быстро приступить к работе, или если у вас большой API и вы хотите обеспечить последовательную конфигурацию URL во всем.
Маршрутизаторы по умолчанию, входящие в состав DRF, обеспечивают маршруты для стандартного набора действий в стиле create/retrieve/update/destroy, как показано ниже:
Во время диспетчеризации для 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
. Например:
Декоратор позволяет переопределить любую конфигурацию на уровне набора представлений, такую как permission_classes
, serializer_class
, filter_backends
...:
Два новых действия будут доступны по адресам ^users/{pk}/set_password/$
и ^users/{pk}/unset_password/$
. Используйте параметры url_path
и url_name
для изменения сегмента URL и обратного имени URL действия.
Чтобы просмотреть все дополнительные действия, вызовите метод .get_extra_actions()
.
Дополнительные действия могут сопоставлять дополнительные HTTP-методы с отдельными методами ViewSet
. Например, описанные выше методы установки и снятия пароля могут быть объединены в один маршрут. Обратите внимание, что дополнительные сопоставления не принимают аргументов.
Если вам нужно получить URL-адрес действия, используйте метод .reverse_action()
. Это удобная обертка для reverse()
, автоматически передающая объект request
представления и дополняющая url_name
атрибутом .basename
.
Обратите внимание, что basename
предоставляется маршрутизатором во время регистрации ViewSet
. Если вы не используете маршрутизатор, то вы должны предоставить аргумент basename
методу .as_view()
.
Используя пример из предыдущего раздела:
В качестве альтернативы можно использовать атрибут url_name
, установленный декоратором @action
.
Аргумент url_name
для .reverse_action()
должен совпадать с тем же аргументом декоратора @action
. Кроме того, этот метод можно использовать для отмены действий по умолчанию, таких как list
и create
.
Класс ViewSet
наследуется от APIView
. Вы можете использовать любые стандартные атрибуты, такие как permission_classes
, authentication_classes
, чтобы управлять политикой API для набора представлений.
Класс ViewSet
не предоставляет никаких реализаций действий. Чтобы использовать класс ViewSet
, вам нужно переопределить его и явно определить реализацию действий.
Класс GenericViewSet
наследуется от GenericAPIView
и предоставляет стандартный набор методов get_object
, get_queryset
и другие базовые поведения общих представлений, но по умолчанию не включает никаких действий.
Чтобы использовать класс GenericViewSet
, вы должны переопределить его и либо смешать необходимые классы mixin, либо явно определить реализацию действий.
Класс ModelViewSet
наследуется от GenericAPIView
и включает в себя реализации различных действий, смешивая поведение различных классов-миксинов.
Класс ModelViewSet
предоставляет следующие действия: .list()
, .retrieve()
, .create()
, .update()
, .partial_update()
и .destroy()
.
Пример
Поскольку ModelViewSet
расширяет GenericAPIView
, вам обычно нужно предоставить как минимум атрибуты queryset
и serializer_class
. Например:
Обратите внимание, что вы можете использовать любой из стандартных атрибутов или переопределений методов, предоставляемых GenericAPIView
. Например, чтобы использовать ViewSet
, который динамически определяет набор запросов, с которым он должен работать, вы можете сделать что-то вроде этого:
Также обратите внимание, что хотя этот класс по умолчанию предоставляет полный набор действий create/list/retrieve/update/destroy, вы можете ограничить доступные операции с помощью стандартных классов разрешений.
Класс ReadOnlyModelViewSet
также наследуется от GenericAPIView
. Как и ModelViewSet
, он также включает реализации различных действий, но в отличие от ModelViewSet
предоставляет только действия "только для чтения", .list()
и .retrieve()
.
Пример
Как и в случае с ModelViewSet
, обычно вам нужно предоставить как минимум атрибуты queryset
и serializer_class
. Например:
Как и в случае с ModelViewSet
, вы можете использовать любые стандартные атрибуты и переопределения методов, доступные для GenericAPIView
.
Вам может понадобиться предоставить пользовательские классы ViewSet
, которые не имеют полного набора действий ModelViewSet
или настраивают поведение каким-либо другим способом.
Чтобы создать базовый класс набора представлений, обеспечивающий операции create
, list
и retrieve
, наследуйте от GenericViewSet
и добавьте необходимые действия:
Создавая собственные базовые классы ViewSet
, вы можете обеспечить общее поведение, которое может быть повторно использовано в нескольких наборах представлений в вашем API.
Аргумент methods
также поддерживает методы HTTP, определенные как . Пример ниже идентичен приведенному выше:
Однако обратите внимание, что, после удаления свойства queryset
из вашего ViewSet
, любой связанный с ним не сможет автоматически вывести базовое имя вашей Модели, поэтому вам придется указать именованный аргумент basename
как часть вашей регистрации .