zoukankan      html  css  js  c++  java
  • django rest framework响应数据的源码分析

    由于 rest framework自带的接口没有响应的状态码,所以我一直都想给返回的数据里面加上接口请求的状态码,于是今天特地去翻了一下源码

    由于我用的视图类ModelViewSet继承了rest_framework.mixins.CreateModelMixin,rest_framework.mixins.RetrieveModelMixin,rest_framework.mixins.UpdateModelMixin,

    rest_framework.mixins.DestroyModelMixin,rest_framework.mixins.ListModelMixin,rest_framework.rest_framework.viewsets.GenericViewSet类

    在mixins.py中定义了5种请求的类,他们各自定义了对应请求的方法,返回相应的数据。

    class ModelViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericViewSet):
        """
        A viewset that provides default `create()`, `retrieve()`, `update()`,
        `partial_update()`, `destroy()` and `list()` actions.
        """
        pass
    
    class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
        """
        The GenericViewSet class does not provide any actions by default,
        but does include the base set of generic view behavior, such as
        the `get_object` and `get_queryset` methods.
        """
        pass

    当使用list方法获取数据的时候他会对数据做分页处理

    class ListModelMixin:
        """
        List a queryset.
        """
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)

    在这里的get_paginated_response方法在GenericViewSet类中做了定义

    class GenericAPIView(views.APIView):
          def get_paginated_response(self, data):
            """
            Return a paginated style `Response` object for the given output data.
            """
            assert self.paginator is not None
            return self.paginator.get_paginated_response(data)
        @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

    这里的paginator方法中调用的是我们在视图中定义的分页类,如:

    class DefaultPagination(PageNumberPagination):
        page_size = 10

    这里的继承了PageNumberPagination类

    class PageNumberPagination(BasePagination):
        def get_paginated_response(self, data):
            return Response(OrderedDict([
                ('count', self.page.paginator.count),
                ('next', self.get_next_link()),
                ('previous', self.get_previous_link()),
                ('results', data)
            ]))

    这里就返回了我们前端接口中获取的数据结构了

    所以我们就可以定义一个方法get_paginated_status_response在BasePagination类中,然后把PageNumberPagination继承BasePagination类

    class BasePagination(PageNumberPagination):
        page_size_query_param = 'pagesize'
        page_query_param = 'page'
        max_page_size = 1000
    
        def get_paginated_status_response(self, data,status=1):
            return Response(OrderedDict([
                ('count', self.page.paginator.count),
                ('next', self.get_next_link()),
                ('previous', self.get_previous_link()),
                ('results', data),
                ('status',status)
            ]))

    定义一个继承ModelViewSet类的派生类,并重写get_paginated_response方法及list方法

    class BaseView(ReturnFormatMixin, viewsets.ModelViewSet):
        queryset = None
        serializer_class = None
        permission_classes = []
        # 分页
        pagination_class = DefaultPagination
        search_fields = []
        def get_paginated_status_response(self, data,status):
            """
            Return a paginated style `Response` object for the given output data.
            """
            assert self.paginator is not None
            return self.paginator.get_paginated_response(data,status)
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(
                 OrderedDict(
                     ('results',serializer.data),
                     ('status',1)
                 ))        

    这样就能返回带状态的数据了,其他请求也是以此类推,重写对应的方法

  • 相关阅读:
    在线|九月月考选填题
    函数$f(x)=e^xpm e^{-x}$相关
    偶函数性质的推广
    2020年全国卷Ⅱ卷文科数学选填题解析版
    2020年全国卷Ⅱ卷文科数学解答题解析版
    待定系数法
    特殊方法求函数解析式
    phd文献阅读日志-4.1
    phd文献阅读日志-1.2~3.2(1.2,2.1,2.2,3.1,3.2)
    完美解决linux下vim在终端不能用鼠标复制的问题
  • 原文地址:https://www.cnblogs.com/arrow-kejin/p/14628045.html
Copyright © 2011-2022 走看看