rest framework Genericview
通用视图
Django的通用视图...被开发为普通使用模式的快捷方式......他们采取某些共同的习惯和模式的发展观和抽象,从而使您可以快速地将数据写入的共同看法,而不必重复自己发现的。
- Django文档
一个基于类的意见主要好处是它们允许你撰写的可重复使用的行为位的方式。REST架构充分利用了这通过提供一系列技术,可为常用的模式预先构建的意见。
通过REST框架提供的通用视图允许您快速建立密切映射到你的数据库模型API意见。
如果通用视图不适合你的API的需求,您可以下降到使用常规APIView
类,或重新使用的通用视图来编写自己的一套可重用的通用视图的混入和基类。
例子
通常使用普通视图时,你会覆盖视图,并设置一些类属性。
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参考
GenericAPIView
此类扩展REST框架的APIView
类,增加了标准列表和详细信息视图通常所需的行为。
所提供的具体的通用视图分别由建相结合GenericAPIView
,与一个或多个混入类。
属性
基本设置:
下面的属性控制的基本看法行为。
queryset
-应该用于从该视图返回对象的查询集。通常情况下,您必须设置该属性,或覆盖的get_queryset()
方法。如果您正在覆盖一个观点方法,你把它是非常重要的get_queryset()
,而不是直接访问这个属性的,如queryset
将得到评估一次,这些结果会被缓存以后的所有请求。serializer_class
-应该用于验证和反序列化输入,以及用于串行化输出的串行器类。通常情况下,您必须设置该属性,或覆盖的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
保存和删除挂钩:
通过混入类提供了以下的方法,并提供容易重写对象保存或删除行为的。
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)
其他方法:
你通常不会需要覆盖下面的方法,虽然你可能需要,如果你正在编写自定义视图使用调入它们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)
- 给定一个查询集,以取其过滤器后端都在使用它进行过滤,返回一个新的查询集。
混入
该混入类提供用于提供基本视图行为的行动。需要注意的是混入类提供的操作方法,而不是定义的处理方法,比如.get()
和.post()
直接。这使得行为更加灵活组成。
该混入类可以从进口rest_framework.mixins
。
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
自定义通用视图
通常你会希望使用现有的一般看法,但使用一些轻微的定制行为。如果你发现自己重复使用在多个地方定制行为的某些位,则可能需要重构行为变成一个公共类,您可以根据需要那么就适用于任何视图或视图集。
创建自定义的混入
例如,如果你需要基于URL的conf多个字段来查找对象,你可以创建一个混合类像下面这样:
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']
使用自定义的混入是,如果你有自定义行为将要使用需要一个很好的选择。
创建自定义的基类
如果使用的是跨多个视图一个mixin,你可以借此更进一步,创建你自己的一套,然后可以在整个项目中使用的基本视图。例如:
class BaseRetrieveView(MultipleFieldLookupMixin,
generics.RetrieveAPIView):
pass
class BaseRetrieveUpdateDestroyView(MultipleFieldLookupMixin,
generics.RetrieveUpdateDestroyAPIView):
pass
使用自定义的基类是如果你有持续需要在大量的意见在整个项目中重复自定义行为一个不错的选择。
把尽可能创造
3.0版本之前,治疗的REST框架混入PUT
作为任何更新或创建操作,取决于如果该对象已存在与否。
允许PUT
作为创建操作是有问题的,因为它必然暴露有关的存在或对象不存在的信息。它也并不明显,它透明,允许之前删除的情况下重新建立一定比简单地返回一个更好的默认行为404
的反应。
这两种风格“ PUT
404”和“ PUT
为打造”可以在不同的情况下有效,但是从3.0版本开始,我们现在使用404的行为默认的,因为它有更简单,更明显。
如果需要通用PUT,为创建行为,你可能要包括像这个AllowPUTAsCreateMixin
类的混入你的意见。
第三方软件包
下面的第三方软件包提供额外的通用视图实现。
Django的休息多模型
Django的休息多模型提供了用于经由单个API请求发送多个串行化模式和/或查询集的通用视图(以及混入)。