开发环境:Ubuntu16.04+Python3.5x+Pycharm2018.2python
包含方法和属性的通用视图基类及扩展类的继承关系数据库
本篇主要说明GenericAPIView类
rest_framework.generics.GenericAPIView后端
继承自APIView,增长了对于列表视图和详情视图可能用到的通用支持方法。一般使用时,可搭配一个或多个Mixin扩展类.api
支持定义的属性:框架
列表视图与详情视图通用:
queryset 列表视图的查询集
serializer_class 视图使用的序列化器ide
列表视图使用:
pagination_class 分页控制类
filter_backends 过滤控制后端ui
详情页视图使用:
lookup_field 查询单一数据库对象时使用的条件字段,默认为'pk'
lookup_url_kwarg 查询单一数据时URL中的参数关键字名称,默认与look_field相同this
源代码以下:lua
queryset = None serializer_class = None # If you want to use object lookups other than pk, set 'lookup_field'. # For more complex lookup requirements override `get_object()`. lookup_field = 'pk' lookup_url_kwarg = None # The filter backend classes to use for queryset filtering filter_backends = api_settings.DEFAULT_FILTER_BACKENDS # The style to use for queryset pagination. pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
支持定义的方法:url
列表视图与详情视图通用:
get_queryset(self)
源码以下:
def get_queryset(self): """ Get the list of items for this view. This must be an iterable, and may be a queryset. Defaults to using `self.queryset`. This method should always be used rather than accessing `self.queryset` directly, as `self.queryset` gets evaluated only once, and those results are cached for all subsequent requests. You may want to override this if you need to provide different querysets depending on the incoming request. (Eg. return a list of items that is specific to the user) """ assert self.queryset is not None, ( "'%s' should either include a `queryset` attribute, " "or override the `get_queryset()` method." % self.__class__.__name__ ) queryset = self.queryset if isinstance(queryset, QuerySet): # Ensure queryset is re-evaluated on each request. queryset = queryset.all() return queryset
返回视图使用的查询集,是列表视图与详情视图获取数据的基础,默认返回queryset属性,能够重写,例如:
def get_queryset(self): user = self.request.user return user.accounts.all()
get_serializer_class(self)
def get_serializer_class(self): """ Return the class to use for the serializer. Defaults to using `self.serializer_class`. You may want to override this if you need to provide different serializations depending on the incoming request. (Eg. admins get full serialization, others get basic serialization) """ assert self.serializer_class is not None, ( "'%s' should either include a `serializer_class` attribute, " "or override the `get_serializer_class()` method." % self.__class__.__name__ ) return self.serializer_class
返回序列化器类,默认返回serializer_class,能够重写,例如:
def get_serializer_class(self): if self.request.user.is_staff: return FullAccountSerializer return BasicAccountSerializer
get_serializer(self, args, **kwargs)
返回序列化器对象,被其余视图或扩展类使用,若是咱们在视图中想要获取序列化器对象,能够直接调用此方法。
注意,在提供序列化器对象的时候,REST framework会向对象的context属性补充三个数据:request、format、view,这三个数据对象能够在定义序列化器时使用。
详情视图使用:
get_object(self)
def get_object(self): """ Returns the object the view is displaying. You may want to override this if you need to provide non-standard queryset lookups. Eg if objects are referenced using multiple keyword arguments in the url conf. """ queryset = self.filter_queryset(self.get_queryset()) # Perform the lookup filtering. lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field assert lookup_url_kwarg in self.kwargs, ( 'Expected view %s to be called with a URL keyword argument ' 'named "%s". Fix your URL conf, or set the `.lookup_field` ' 'attribute on the view correctly.' % (self.__class__.__name__, lookup_url_kwarg) ) filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]} obj = get_object_or_404(queryset, **filter_kwargs) # May raise a permission denied self.check_object_permissions(self.request, obj) return obj
返回详情视图所需的模型类数据对象,默认使用lookup_field参数来过滤queryset。 在试图中能够调用该方法获取详情信息的模型类对象。
若详情访问的模型类对象不存在,会返回404。
def get_object_or_404(queryset, *filter_args, **filter_kwargs): """ Same as Django's standard shortcut, but make sure to also raise 404 if the filter_kwargs don't match the required types. """ try: return _get_object_or_404(queryset, *filter_args, **filter_kwargs) except (TypeError, ValueError, ValidationError): raise Http404
该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。
举例:以图书与英雄案例(如水浒传与英雄)
# GET /books/ # url(r'^books/$', views.BookListAPIView.as_view()) 对应的路由 class BookListAPIView(GenericAPIView): """ 数据查询集 """ queryset = BookInfo.objects.all() # 数据库查询集 serializer_class = BookInfoSerializer def get(self,request): # 数据库查询 qs = self.get_queryset() # 构建序列化器对象,进行序列化操做 serializer = self.get_serializer(qs,many = True) return Response(serializer.data) # GET /books/<pk>/ # url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()) 对应的路由 class BookDetailAPIView(GenericAPIView): queryset = BookInfo.objects.all() serializer_class = BookInfoSerializer def get(self,request,pk): """ 查询单个 :param query: :return: """ book = self.get_object() serializer = self.get_serializer(book) return Response(serializer.data)