提高提供# Generic views
Django’s generic views... were developed as a shortcut for common usage patterns... They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to repeat yourself.
— Django Documentation
基于类的视图的优点之一是,它允许你将一些可重用的行为进行组合,REST framework提供了许多常用的预构建视图来充分利用这一优点。
REST framework提供的通用视图允许你快速构建与识图模型紧密对应的API视图。
如果通用视图不符合你的API的需求,你可以使用常规的APIView类,或者重用通用视图使用的mixins和base类(基类)来构建你自己的可重用视图。
Examples
通常使用通用视图时,你需要覆盖视图,并提供介个类参数:
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 Reference
GenericAPIView
该类继承自REST framework的APIView类,在此基础上为标准的list和detail视图添加了通用的操作。
该类提供的每个具体的通用视图都是将GenericAPIView与一个或多个mixin类组合在一起构建的。
Attributes
Basic settings:
下面的属性控制着视图的基本行为:
queryset-从此视图返回对象的查询器。通常,你必须设置此属性,或者覆盖get_queryset()方法,如果你覆盖了一个视图的方法,那么调用get_queryset()方法而不是直接访问此属性非常重要,因为查询后将会赋值,这个结果将会被缓存下来供后续的请求使用。serializer_class-用于校验,序列化输入和反序列化输出的序列化类。通常,你要么设置此属性,要么覆盖get_serializer_class()方法。lookup_field-单个model实例对象查找的字段(如id),默认为“pk”。注意,使用超链接API时,如果需要使用自定义值,则需要确保API视图和序列化类都设置了该查找字段。lookup_url_kwarg-用于对象查找的URL关键字参数。URL conf应包含与该值想对应的关键字参数,如果没有设置该值,则默认使用与lookup_field相同的关键字参数。
Pagination:
在使用list view时,下面的属性被用来控制分页:
pagination_class-分页展示数据时要使用pagination类。默认使用与settings中DEFAULT_PAGINATION_CLASS相同的值,即rest_framework.pagination.PageNumberPagination。设置pagination_class=None将会在此页面禁用分页。
Filtering:
filter_backends-用于过滤数据集的后端类的列表。默认使用与settings中DEFAULT_FILTER_BACKENDS相同的值。
Methods
基本方法:
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参数从queryset中过滤数据。
可以覆盖该方法来实现更加复杂的操作,例如你的url中有多个参数,要利用这些参数进行查询:
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)
提供一个查询集,然后用一个过滤器来过滤它并返回过滤后的数据集。 例子:
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
返回使用的序列化器,默认返回的是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调用
这些钩子函数特别适用于设置那些在request中隐含的、但却不是请求数据的属性。例如,你可以给对象设置请求的用户,或者设置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):提供一个查询集,使用正在使用的filter backends 来过滤它,然后返回一个新的查询集。
Mixins
mixins类提供了用于提供基本视图行为的方法。注意,mixins提供的是操作方法,而不是直接定义了像.post()和.get()这样的处理方法。这样可以更加灵活的组织你需要的各种操作。
mixin类可以从rest_framework.mixins中导入。
ListModelMixin
提供了`.list(request, *args, **kwargs)方法用来列出查询集。
如果查询集(queryset)有数据,将会反回200 OK响应,并将序列化后的数据作为响应体(response body)。可依选择是否对数据进行分页。
CreateModelMixin
提供了.create(request, *args, **kwargs)方法来创建和保存新的对象实例。
如果对象被成功创建则返回201 Created响应,并将序列化后的对象作为响应体。如果该数据中包含一个名为url的键,那么响应的Location头部将会使用该值。
如果创建该对象的请求数据无效,将会反回400 Bad Request响应,并将错误的详细信息作为响应体。
RetrieveModelMixin
提供了.retrieve(request, *args, **kwargs)方法在response中返回一个已经存在的对象实例。
如果对象可以被获取到,将返回200 OK响应并将序列化后的对象作为响应体,否则将返回404 Not Found.
UpdateModelMixin
提供了.update(request, *args, **kwargs)方法来更新和保存已经存在的对象实例。
也提供了.partial_update(request, *args, **kwargs)``方法,它与update方法非常相似。不同的是,partial_update方法中可以选择要更新哪些字段,它还支持PATCH```请求。
如果更新该对象的请求数据无效,将会反回400 Bad Request响应,并将错误的详细信息作为响应体。
DestroyModelMixin
提供了.destroy(request, *args, **kwargs)方法来删除一个已经存在的对象实例。
如果对象被成功删除则返回204 No Content响应,否则返回404 Not Found.
Concrete View Classes
下面是具体的通用视图。如果你正在史通通用视图,你只需要基于下面的视图来开始你的工作即可,除非你需要大量定制自己的视图。
这些视图类可以从rest_framework.generics中导入。
CreateAPIView
它仅仅用来创建数据,提供了一个post方法处理器。
继承自:GenericAPIView,CreateModelMixin
ListAPIView
提供了一个get方法c狐狸起,用来获取数据集合。
继承:GenericAPIView,ListModelMixin
RetrieveAPIView
提供了一个get方法c狐狸起,用来获取单条数据。
继承:GenericAPIView,RetrieveModelMixin
UpdateAPIView
提供了post和patch方法处理器,用来更新单条数据。
继承:GenericAPIView,UpdateModelMixin
DestroyAPIView
提供了delete方法处理器,用来删除单条记录。
继承:GenericAPIView,DestroyModelMixin
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