Руководство по API платформы Django REST (1): запросы
Руководство по API платформы Django REST (2): ответы
Руководство по API платформы Django REST (3): представления
Руководство по API платформы Django REST (4): общие представления
Руководство по API платформы Django REST (5): наборы представлений
Руководство по API Django REST framework (6): Маршрутизация
Руководство по API платформы Django REST (7): анализ
Набор видов
После того, как маршрутизация решила, какой контроллер использовать для запроса, контроллер отвечает за понимание запроса и создание соответствующего вывода.
—Документация по Ruby on Rails
Фреймворк Django REST позволяет объединить логику набора связанных представлений в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):
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)
При желании это представление можно объединить в два отдельных представления следующим образом:
user_list = UserViewSet.as_view({'get': 'list'})
user_detail = UserViewSet.as_view({'get': 'retrieve'})
Обычно мы этого не делаем, а регистрируем набор представлений на маршрутизаторе и разрешаем автоматическую генерацию urlconf.
from myapp.views import UserViewSet
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'users', UserViewSet, base_name='user')
urlpatterns = router.urls
Вместо написания собственного набора представлений вы обычно используете существующие базовые классы, предоставляемые по умолчанию. Например:
class UserViewSet(viewsets.ModelViewSet):
"""
用于查看和编辑用户实例的视图。
"""
serializer_class = UserSerializer
queryset = User.objects.all()
использоватьViewSet
Есть два основных преимущества использования класса View по аналогии.
- Дублирующаяся логика может быть объединена в один класс. В приведенном выше примере нам нужно указать набор запросов только один раз, и он будет использоваться в нескольких представлениях.
- Используя маршрутизаторы, нам больше не нужно обрабатывать вашу конфигурацию URL.
Оба имеют свои преимущества и недостатки. Используйте обычные представления и файлы конфигурации URL более четко и дайте вам больше элементов управления. Если вы хотите быстро разработать приложение, или необходимо сделать конфигурацию URL-URL-URL больших API, соберее всего очень полезно.
Управление наборами представлений
Маршруты по умолчанию, включенные в структуру REST, будут предоставлять маршруты для стандартного набора действий стиля создания/получения/обновления/удаления следующим образом:
class UserViewSet(viewsets.ViewSet):
"""
这些方法将由路由器负责处理。
如果要使用后缀,请确保加上 `format = None` 关键字参数
"""
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
Во время отправки к имени текущего действия можно получить доступ через.action
полученное имущество. ты можешь проверить.action
для настройки поведения на основе текущего действия.
Например, вы можете ограничить доступ только для администратора.list
Действия, кроме следующих:
def get_permissions(self):
"""
实例化并返回此视图所需的权限列表。
"""
if self.action == 'list':
permission_classes = [IsAuthenticated]
else:
permission_classes = [IsAdmin]
return [permission() for permission in permission_classes]
Отметить дополнительное поведение маршрутизации
Если вам нужно направить определенный метод, вы можете использовать@detail_route
или@list_route
декоратор для украшения.
@detail_route
Декоратор содержит в своем шаблоне URLpk
, чтобы поддерживать методы, которые необходимо получить один экземпляр.@list_route
Модификатор подходит для метода работы со списком объектов.
Возьмите каштан:
from django.contrib.auth.models import User
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from myapp.serializers import UserSerializer, PasswordSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
提供标准操作的视图集
"""
queryset = User.objects.all()
serializer_class = UserSerializer
@detail_route(methods=['post'])
def set_password(self, request, pk=None):
user = self.get_object()
serializer = PasswordSerializer(data=request.data)
if serializer.is_valid():
user.set_password(serializer.data['password'])
user.save()
return Response({'status': 'password set'})
else:
return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
@list_route()
def recent_users(self, request):
recent_users = User.objects.all().order('-last_login')
page = self.paginate_queryset(recent_users)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(recent_users, many=True)
return Response(serializer.data)
Кроме того, декоратор может задать дополнительные параметры для просмотра маршрута. Например...
@detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
...
Маршруты этих декораторов по умолчаниюGET
запрос, но также может использоватьmethods
Параметры принимают другие методы HTTP. Например:
@detail_route(methods=['post', 'delete'])
def unset_password(self, request, pk=None):
...
Эти две новые операции будут URL-адресами^users/{pk}/set_password/$
и^users/{pk}/unset_password/$
начальство.
Действие прыгать
Если вам нужно получить URL-адрес действия, используйте.reverse_action()
метод. Это.reverse()
Удобная оболочка, которая автоматически передает объект запроса представления иurl_name
и.basename
Атрибуты крючки.
Пожалуйста, обрати внимание,basename
вViewSet
Предоставляется роутером при регистрации. Если вы не используете маршрутизатор, вы должны предоставить.as_view()
методbasename
параметр.
Используя пример из предыдущего раздела:
>>> view.reverse_action('set-password', args=['1'])
'http://localhost:8000/api/users/1/set_password'
url_name
Параметр должен быть таким же, как@list_route
и@detail_route
Тот же аргумент декоратора совпадает. Кроме того, это можно использовать для инвертирования значения по умолчанию.list
иdetail
маршрутизация.
Справочник по API
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
Атрибуты. Например:
class AccountViewSet(viewsets.ModelViewSet):
"""
用于查看和编辑 Account
"""
queryset = Account.objects.all()
serializer_class = AccountSerializer
permission_classes = [IsAccountAdminOrReadOnly]
Обратите внимание, что вы можете переопределитьGenericAPIView
Любой стандартный метод или предоставляется свойство. Например, динамически определить набор запросов, которые оно должно управлятьViewSet
, что можно сделать так:
class AccountViewSet(viewsets.ModelViewSet):
"""
A simple ViewSet for viewing and editing the accounts
associated with the user.
"""
serializer_class = AccountSerializer
permission_classes = [IsAccountAdminOrReadOnly]
def get_queryset(self):
return self.request.user.accounts.all()
Но учтите, что изViewSet
Удалитьqueryset
свойство, любые связанные маршрутизаторы не смогут автоматически экспортировать модельbase_name
, поэтому вы должны положитьbase_name
Kwarg указывается как часть регистрации маршрутизатора.
Также обратите внимание, что, хотя этот класс по умолчанию предоставляет полный набор операций создания/списка/получения/обновления/уничтожения, вы можете ограничить доступные операции, используя стандартные классы разрешений.
ReadOnlyModelViewSet
ReadOnlyModelViewSet
класс тоже изGenericAPIView
наследовать. иModelViewSet
Мол, он тоже содержит реализацию различных операций, но сModelViewSet
Разница в том, что он обеспечивает только операции «только для чтения»,.list()
и.retrieve()
.
Возьмите каштан:
иModelViewSet
Например, вам обычно нужно предоставить как минимумqueryset
иserializer_class
Атрибуты. Например:
class AccountViewSet(viewsets.ReadOnlyModelViewSet):
"""
A simple ViewSet for viewing accounts.
"""
queryset = Account.objects.all()
serializer_class = AccountSerializer
Точно так же сModelViewSet
Например, вы можете переопределитьGenericAPIView
Доступны любые стандартные свойства и методы.
Набор базовых классов на заказ
Вам не может использовать полныйModelViewSet
Настройка наборов действийViewSet
класс или другое пользовательское поведение.
Возьмите каштан:
Чтобы создать предложениеcreate
,list
иretrieve
Базовый класс набора представлений для операций, начиная сGenericViewSet
Наследовать и смешать нужные операции:
from rest_framework import mixins
class CreateListRetrieveViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
"""
A viewset that provides `retrieve`, `create`, and `list` actions.
To use it, override the class and set the `.queryset` and
`.serializer_class` attributes.
"""
pass
Создав собственную базовуюViewSet
Классы, которые обеспечивают общее поведение, которое можно повторно использовать в нескольких наборах представлений в API.