您的位置:首页 > 编程语言 > Go语言

Django REST framework-API指南04-Generic views 原创翻译

2017-10-09 21:26 549 查看
python技术交流群332680349,资源分享,技术交流。

类的视图

Django的类视图…被开发为常见使用模式的快捷方式…他们采取在视图开发中发现的一些常见习语和模式,并将其抽象出来,以便您可以快速编写数据的常见视图,而无需重复。

—-Django文档

基于类视图的主要优点之一是它们允许您组合可重用行为的方式。REST框架来利用这个优势,通过提供许多提供常用模式的预构建视图。

REST框架提供的类视图允许您快速构建与数据库模型紧密对应的API视图。

如果类视图不符合您的API需求,则APIView可以使用常规类,或者重用类视图使用的mixins和base类来构建您自己的一组可重用的类视图。

例子

通常当使用类视图时,您将覆盖视图,并设置几个类属性。

from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics
from rest_framework.permissions import IsAdminUser

class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAdminUser,)


对于更复杂的情况,您可能还想覆盖视图类上的各种方法。例如。

class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAdminUser,)

def list(self, request):
# Note the use of `get_queryset()` instead of `self.queryset`
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)


对于非常简单的情况,您可能希望使用该.as_view()方法传递任何类属性。例如,您的URLconf可能包含以下条目:

url(r'^/users/', ListCreateAPIView.as_view(queryset=User.objects.all(), serializer_class=UserSerializer), name='user-list')


API参考

类的API视图

此类扩展了REST框架的APIView类,为标准列表和详细视图添加了常见的请求行为。

提供的每个具体类视图是通过GenericAPIView与一个或多个mixin类组合来构建的。

属性

基本设置:

以下属性控制基本视图行为。

queryset - 用于从此视图返回对象的查询器集。通常,您必须设置此属性,或覆盖该get_queryset()方法。如果您覆盖了一个视图方法,那么重要的是您需要get_queryset()代替直接访问此属性,而是调用queryset一次,并且将为所有后续请求缓存那些结果。

serializer_class - 用于验证和反序列化输入以及序列化输出的serializer类。通常,您必须设置此属性,或覆盖该get_serializer_class()方法。

lookup_field - 应用于执行单个模型实例的对象查找的模型字段。默认为’pk’。请注意,使用超链接的API时,您需要确保API视图和串行类设置查找字段,如果你需要使用一个自定义值。

lookup_url_kwarg - 应该用于对象查找的URL关键字参数。URL conf应包含与该值对应的关键字参数。如果取消设置,则默认使用与之相同的值lookup_field。

分页:

当与列表视图一起使用时,以下属性用于控制分页。

pagination_class - 有分页列表结果时应使用的分页类。默认值与DEFAULT_PAGINATION_CLASS设置值相同’rest_framework.pagination.PageNumberPagination’。设置pagination_class=None将在此视图上禁用分页。

过滤:

filter_backends - 应用于过滤查询集的过滤器后端类的列表。默认值与DEFAULT_FILTER_BACKENDS设置相同。

方法

基本方法:

get_queryset(self)


返回应该用于列表视图的查询集,并且应该将其用作查看详细视图的基础。默认返回queryset属性指定的查询集。

应始终使用此方法,而不是self.queryset直接访问,因为self.queryset只得到一次评估,并且为所有后续请求缓存这些结果。

可能会被覆盖以提供动态行为,例如返回特定于发出请求的用户的查询集。

例如:

def get_queryset(self):
user = self.request.user
return user.accounts.all()


get_object(self)


返回应用于详细视图的对象实例。默认使用lookup_field参数过滤基本查询集。

可能会被覆盖以提供更复杂的行为,例如基于多个URL kwarg的对象查找。

例如:

def get_object(self):
queryset = self.get_queryset()
filter = {}
for field in self.multiple_lookup_fields:
filter[field] = self.kwargs[field]

obj = get_object_or_404(queryset, **filter)
self.check_object_permissions(self.request, obj)
return obj


请注意,如果您的API不包括任何对象级权限,则可以选择性地排除self.check_object_permissions该对象,并简单地从get_object_or_404查找返回对象。

filter_queryset(self, queryset)


给定一个查询集,使用任何过滤器后端进行过滤,返回一个新的查询集。

例如:

def filter_queryset(self, queryset):
filter_backends = (CategoryFilter,)

if 'geo_route' in self.request.query_params:
filter_backends = (GeoRouteFilter, CategoryFilter)
elif 'geo_point' in self.request.query_params:
filter_backends = (GeoPointFilter, CategoryFilter)

for backend in list(filter_backends):
queryset = backend().filter_queryset(self.request, queryset, view=self)

return queryset


get_serializer_class(self)


返回应该用于序列化程序的类。默认返回serializer_class属性。

可能会被覆盖以提供动态行为,例如使用不同的串行器进行读写操作,或为不同类型的用户提供不同的序列化程序。

例如:

def get_serializer_class(self):
if self.request.user.is_staff:
return FullAccountSerializer
return BasicAccountSerializer


保存和删除钩子:

以下方法由mixin类提供,并提供容易覆盖对象保存或删除行为。

perform_create(self, serializer)- CreateModelMixin保存新对象实例时调用。

perform_update(self, serializer)- UpdateModelMixin保存现有对象实例时调用。

perform_destroy(self, instance)- DestroyModelMixin删除对象实例时调用。

这些钩子特别适用于设置请求中隐性的属性,但不是请求数据的一部分。例如,您可以根据请求用户或基于URL关键字参数在对象上设置属性。

def perform_create(self, serializer):
serializer.save(user=self.request.user)


这些覆盖点对于添加在保存对象之前或之后发生的行为(例如发送确认或记录更新)也特别有用。

def perform_update(self, serializer):
instance = serializer.save()
send_email_confirmation(user=self.request.user, modified=instance)


您也可以使用这些钩子来提供额外的验证,通过ValidationError()。如果您需要在数据库保存时应用一些验证逻辑,这将非常有用。例如:

def perform_create(self, serializer):
queryset = SignupRequest.objects.filter(user=self.request.user)
if queryset.exists():
raise ValidationError('You have already signed up')
serializer.save(user=self.request.user)


注意:这些方法取代旧式的2.x版pre_save,post_save,pre_delete和post_delete方法,这将不再可用。

其他方法:

通常您不需要覆盖以下方法,尽管你可能需要调用他们,如果你用GenericAPIView写一个自定义视图。

get_serializer_context(self) - 返回包含应提供给序列化程序的任何额外上下文的字典。默认为包括’request’,’view’和’format’键。

get_serializer(self, instance=None, data=None, many=False, partial=False) - 返回一个序列化器实例。

get_paginated_response(self, data)- 返回分页样式Response对象。

paginate_queryset(self, queryset)- 如果需要,分页查询集,返回页面对象,或者None如果未为此视图配置分页。

filter_queryset(self, queryset) - 给定一个查询集,使用任何过滤器后端进行过滤,返回一个新的查询集。

Mixins

mixin类提供用于提供基本视图行为的操作。请注意,mixin类提供操作方法,而不是定义处理程序方法,例如像.get()和.post(),直接。这样可以更灵活地组合行为。

可以从rest_framework.mixins中导入mixin类。

ListModelMixin

提供一种.list(request, *args, **kwargs)实现列出查询集的方法。

如果查询集被填充,则返回一个200 OK响应,其中序列化的展示作为响应的主体。响应数据可以可选地被分页。

CreateModelMixin

提供.create(request, *args, **kwargs)一种实现创建和保存新模型实例的方法。

如果创建一个对象,则返回一个201 Created响应,该对象的序列化展示作为响应的主体。如果表示包含一个命名url的键,则响应的Location 头将被填充用该值。

如果提供用于创建对象的请求数据无效,400 Bad Request则将返回响应,其中错误详细信息作为响应的正文。

RetrieveModelMixin

提供一种.retrieve(request, *args, **kwargs)在响应中实现返回现有模型实例的方法。

如果可以检索到对象,则返回一个200 OK响应,并将对象的序列化表述作为响应的正文。否则会返回404 Not Found.

UpdateModelMixin

提供一种.update(request, *args, **kwargs)实现更新和保存现有模型实例的方法。

还提供了.partial_update(request, *args, **kwargs)一种类似于update方法的方法,但更新的所有字段将是可选的。这允许支持HTTP PATCH请求。

如果一个对象被更新,则返回一个200 OK响应,该对象的序列化表述作为响应的主体。

如果提供用于更新对象的请求数据无效,400 Bad Request则将返回响应,错误详细信息作为响应的正文。

DestroyModelMixin

提供一种.destroy(request, *args, **kwargs)实现对现有模型实例的删除的方法。

如果对象被删除,则返回一个204 No Content响应,否则返回一个404 Not Found。

具体的视图类

以下类是具体的通用视图。如果您使用类视图,这通常是您将要工作的级别,除非您需要大量自定义的行为。

视图类可以从中导入rest_framework.generics。

CreateAPIView

用于仅创建端点。

提供一个post方法处理程序

扩展:GenericAPIView,CreateModelMixin

ListAPIView

用于只读端点来表述模型实例的集合。

提供一个get方法处理程序

扩展:GenericAPIView,ListModelMixin

RetrieveAPIView

用于只读端点来表示单一模型实例。

提供一个get方法处理程序

扩展:GenericAPIView,RetrieveModelMixin

DestroyAPIView

用于单一模型实例的仅删除端点。

提供一个delete方法处理程序

扩展:GenericAPIView,DestroyModelMixin

UpdateAPIView

用于单一模型实例的仅更新端点。

提供put和patch方法处理程序。

扩展:GenericAPIView,UpdateModelMixin

ListCreateAPIView

用于读写端点来表示模型实例的集合。

提供get和post方法处理程序。

扩展:GenericAPIView,ListModelMixin,CreateModelMixin

RetrieveUpdateAPIView

用于读取或更新端点以表示单一模型实例。

提供get,put并且patch方法处理。

扩展:GenericAPIView,RetrieveModelMixin,UpdateModelMixin

RetrieveDestroyAPIView

用于读取或删除端点以表示单一模型实例。

提供get和delete方法处理程序。

扩展:GenericAPIView,RetrieveModelMixin,DestroyModelMixin

RetrieveUpdateDestroyAPIView

用于读写删除端点来表示单一模型实例。

提供get,put,patch和delete方法处理。

扩展:GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin

自定义通用的视图

通常,您将需要使用现有的类视图,但使用一些稍微自定义的行为。如果您发现自己在多个地方重复使用一些自定义行为,您可能需要将行为重构为通用类,然后可以根据需要将其应用于任何视图集合或视图。

创建自定义mixins

例如,如果您需要根据URL conf中的多个字段查找对象,则可以创建一个类似如下的mixin类:

class MultipleFieldLookupMixin(object):
"""
Apply this mixin to any view or viewset to get multiple field filtering
based on a `lookup_fields` attribute, instead of the default single field filtering.
"""
def get_object(self):
queryset = self.get_queryset()             # Get the base queryset
queryset = self.filter_queryset(queryset)  # Apply any filter backends
filter = {}
for field in self.lookup_fields:
if self.kwargs[field]: # Ignore empty fields.
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter)  # Lookup the object
self.check_object_permissions(self.request, obj)
return obj


然后,只要您需要应用自定义行为,就可以简单地将此mixin应用于视图集合或视图。

class RetrieveUserView(MultipleFieldLookupMixin, generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
lookup_fields = ('account', 'username')


如果您需要使用自定义行为,则使用自定义mixins是一个很好的选择。

创建自定义基类

如果您在多个视图中使用mixin,您可以进一步了解并创建自己的一组基本视图,然后可以在整个项目中使用。例如:

class BaseRetrieveView(MultipleFieldLookupMixin,
generics.RetrieveAPIView):
pass

class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,
generics.RetrieveUpdateDestroyAPIView):
pass


使用自定义基类是一个很好的选择,如果您有自定义行为,始终需要在整个项目中的大量视图中重复。

PUT作为创建

在版本3.0之前,将REST框架混合体视为PUT更新或创建操作,具体取决于对象是否已存在。

允许PUT作为创建操作是有问题的,因为它必然暴露关于对象的存在或不存在的信息。透明地允许重新创建先前删除的实例也不是一个更好的默认行为,而不仅仅是返回404响应。

两种样式“ PUT作为404”和“ PUT作为创建”可以在不同的情况下有效,但从3.0版起,我们现在使用404行为作为默认值,因为它更简单和更明显。

如果您需要通用的PUT-as-create行为,您可能希望将类似这样的AllowPUTAsCreateMixin类包含为您的视图的混合。

三方库

以下第三方软件包提供了其他类视图实现。

Django REST Framework bulk

在Django的REST的架构,bulk实现通用视图mixins以及一些普通具体类视图允许通过API请求应用批量操作。

Django Rest Multiple Models

Django Rest多个模型提供类视图(和mixin),用于通过单个API请求发送多个序列化模型和/或查询集。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: