app开发定制【Django】REST_Framework框架——GenericAPIView类源码解析

一、GenericAPIView解析

GenericAPIView继承自 APIView,也就是在 APIViewapp开发定制基础上再做了一层封装

类属性

queryset = None
serializer_class = None
lookup_field = ‘pk’
lookup_url_kwarg = None
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS

1、queryset

querysetapp开发定制是用来控制视图返回给app开发定制前端的数据。app开发定制如果没什么逻辑,可以直接写在视图的类属性中,如果逻辑比较复杂,也可以重写get_queryset方法用来返回一个queryset对象。如果重写了get_queryset,那么以后获取queryset的时候就需要通过调用get_queryset方法。因为queryset` 这个属性只会调用一次,以后所有的请求都是使用他的缓存。

2、serializer_class

serializer_class用来验证和序列化、反序列化数据的。也是可以通过直接设置这个属性,也可以通过重写get_serializer_class来实现。

3、lookup_field

在检索的时候,根据什么参数进行检索。默认是pk,也就是主键。

4、lookup_url_kwarg

在检索的url中的参数名称。默认没有设置,跟lookup_field保持一致。

5、filter_backends

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

6、pagination_class

当分页列出结果时应使用的分页类。默认值与 DEFAULT_PAGINATION_CLASS 设置的值相同,即 ‘rest_framework.pagination.PageNumberPagination’。

方法

get_object()
get_queryset()
get_serializer()
get_serializer_class()
get_serializer_context()
paginate_queryset()
filter_queryset()

1、get_queryset()

get_queryset默认是返回数据库全部数据,如果想返回其他数据,需要自定义

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

2、get_object()

该方法是用于在数据检索(通过pk查找)的时候,返回一条数据的。
不需要重写get_object(),直接调用

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

3、get_serializer()

返回应该用于验证和反序列化输入以及序列化输出的序列化器实例
不需要重写get_serializer()方法,直接调用即可

def get_serializer(self, *args, **kwargs):        """        Return the serializer instance that should be used for validating and        deserializing input, and for serializing output.        """        serializer_class = self.get_serializer_class()        kwargs.setdefault('context', self.get_serializer_context())        return serializer_class(*args, **kwargs)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4、get_serializer_class()

返回用于序列化的类。默认使用 self.serializer_class。如果您需要根据传入请求提供不同的序列化,您可能需要重写它。

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

5、filter_queryset()

默认不需要过滤,如果需要过滤需要重写filter_queryset()方法

def filter_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 need        to call it either from a list view, or from a custom `get_object`        method if you want to apply the configured filtering backend to the        default queryset.        """        for backend in list(self.filter_backends):            queryset = backend().filter_queryset(self.request, queryset, self)        return queryset
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

6、paginator()

a、paginator()方法让装饰器@property进行修饰,表示将方法暴露出去变成了属性
b、判断类属性中是否包含pagination_class方法,如果存在pagination_class,则变为pagination_class()方法并且赋值给self._paginator,返回self._paginator

    @property    def paginator(self):        """        The paginator instance associated with the view, or `None`.        """        if not hasattr(self, '_paginator'):            if self.pagination_class is None:                self._paginator = None            else:                self._paginator = self.pagination_class()        return self._paginator
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

7、paginate_queryset()

a、默认不需要分页,如果需要分页需要重写paginate_queryset()方法
b、如果self.paginator 为 None,不需要进行过滤,否则需要通过self.paginator.paginate_queryset()方法进行过滤

def paginate_queryset(self, queryset):        """        Return a single page of results, or `None` if pagination is disabled.        """        if self.paginator is None:            return None        return self.paginator.paginate_queryset(queryset, self.request, view=self)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

我的视图

重写了get_queryset()方法和get_serializer_class()方法

from rest_framework.generics import GenericAPIViewfrom rest_framework.response import Responsefrom app2.models import NewsChannelfrom app2.serializers1 import NewsChannelSerializer,NewsChannel1Serializerclass ChannelsAPIView(GenericAPIView):    queryset = NewsChannel.objects.all()    serializer_class = NewsChannelSerializer    def get_queryset(self):        return NewsChannel.objects.filter(id__exact=2)    def get_serializer_class(self):        return NewsChannel1Serializer    def get(self, request,*args,**kwargs):        queryset=self.get_queryset()        serializer=self.get_serializer(instance=queryset,many=True)        return Response(serializer.data)    def post(self,request):        serializer=self.get_serializer(data=request.data)        serializer.is_valid(raise_exception=True)        serializer.save()        return Response(serializer.data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

执行结果:


网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发