classGenericAPIView(views.APIView):"""Base class for all other generic views."""# You'll need to either set these attributes,# or override `get_queryset()`/`get_serializer_class()`.# If you are overriding a view method, it is important that you call# `get_queryset()` instead of accessing the `queryset` property directly,# as `queryset` will get evaluated only once, and those results are cached# for all subsequent requests.queryset =Noneserializer_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 filteringfilter_backends = api_settings.DEFAULT_FILTER_BACKENDS# The style to use for queryset pagination.pagination_class = api_settings.DEFAULT_PAGINATION_CLASSdefget_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 resultsare cached for all subsequent requests.You may want to override this if you need to provide differentquerysets depending on the incoming request.(Eg. return a list of items that is specific to the user)"""assert self.queryset isnotNone,("'%s' should either include a `queryset` attribute, ""or override the `get_queryset()` method."% self.__class__.__name__)queryset = self.querysetifisinstance(queryset, QuerySet):# Ensure queryset is re-evaluated on each request.queryset = queryset.all()return querysetdefget_object(self):"""Returns the object the view is displaying.You may want to override this if you need to provide non-standardqueryset lookups. Eg if objects are referenced using multiplekeyword 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_fieldassert 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 deniedself.check_object_permissions(self.request, obj)return objdefget_serializer(self,*args,**kwargs):"""Return the serializer instance that should be used for validating anddeserializing input, and for serializing output."""serializer_class = self.get_serializer_class()kwargs.setdefault('context', self.get_serializer_context())return serializer_class(*args,**kwargs)defget_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 differentserializations depending on the incoming request.(Eg. admins get full serialization, others get basic serialization)"""assert self.serializer_class isnotNone,("'%s' should either include a `serializer_class` attribute, ""or override the `get_serializer_class()` method."% self.__class__.__name__)return self.serializer_classdefget_serializer_context(self):"""Extra context provided to the serializer class."""return{'request': self.request,'format': self.format_kwarg,'view': self}deffilter_queryset(self, queryset):"""Given a queryset, filter it with whichever filter backend is in use.You are unlikely to want to override this method, although you may needto call it either from a list view, or from a custom `get_object`method if you want to apply the configured filtering backend to thedefault queryset."""for backend inlist(self.filter_backends):queryset = backend().filter_queryset(self.request, queryset, self)return queryset@propertydefpaginator(self):"""The paginator instance associated with the view, or `None`."""ifnothasattr(self,'_paginator'):if self.pagination_class isNone:self._paginator =Noneelse:self._paginator = self.pagination_class()return self._paginatordefpaginate_queryset(self, queryset):"""Return a single page of results, or `None` if pagination is disabled."""if self.paginator isNone:returnNonereturn self.paginator.paginate_queryset(queryset, self.request, view=self)defget_paginated_response(self, data):"""Return a paginated style `Response` object for the given output data."""assert self.paginator isnotNonereturn self.paginator.get_paginated_response(data)
defget_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 differentserializations depending on the incoming request.(Eg. admins get full serialization, others get basic serialization)"""assert self.serializer_class isnotNone,("'%s' should either include a `serializer_class` attribute, ""or override the `get_serializer_class()` method."% self.__class__.__name__)return self.serializer_class
defget_serializer(self,*args,**kwargs):"""Return the serializer instance that should be used for validating anddeserializing input, and for serializing output."""serializer_class = self.get_serializer_class()kwargs.setdefault('context', self.get_serializer_context())return serializer_class(*args,**kwargs)
4.get_queryset(self)
返回视图使用的查询集
主要用来提供Mixin扩展类使用,是列表视图与详情视图获取数据的基础
默认返回queryset属性,可以重写
defget_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 resultsare cached for all subsequent requests.You may want to override this if you need to provide differentquerysets depending on the incoming request.(Eg. return a list of items that is specific to the user)"""assert self.queryset isnotNone,("'%s' should either include a `queryset` attribute, ""or override the `get_queryset()` method."% self.__class__.__name__)queryset = self.querysetifisinstance(queryset, QuerySet):# Ensure queryset is re-evaluated on each request.queryset = queryset.all()return queryset
defget_object(self):"""Returns the object the view is displaying.You may want to override this if you need to provide non-standardqueryset lookups. Eg if objects are referenced using multiplekeyword 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_fieldassert 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 deniedself.check_object_permissions(self.request, obj)return obj