【问题标题】:How can I use pagination_class in django-rest-framework for my custom pagination class如何在 django-rest-framework 中为我的自定义分页类使用 pagination_class
【发布时间】:2015-06-28 11:28:28
【问题描述】:

我的分页类

class ArticleListPagination(PageNumberPagination):
    page_size = 2
    page_size_query_param = 'page_size'

我的文章查看类

class Article(generics.GenericAPIView):

    queryset = Articles.objects.all()
    serializer_class = ArticlesSerializer
    pagination_class = ArticleListPagination

def get(self, request):
    queryset = self.get_queryset()
    serializer = ArticlesSerializer(queryset, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)

我可以使用自定义分页类

def get(self, request):
    queryset = self.get_queryset()
    page = ArticleListPagination()
    new = page.paginate_queryset(queryset, request)
    serializer = ArticlesSerializer(new, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)

这是使用ArticleListPagination的正确方法吗?如果我在课堂上声明我的分页类是ArticleListPagination,为什么它没有改变返回的查询集对象。

【问题讨论】:

    标签: pagination django-rest-framework


    【解决方案1】:

    我更喜欢使用自定义分页,因为它可以让您根据自己的要求修改您的回复。这种方法不需要太多的努力。

    下面是我的代码...希望这会有所帮助。

    custom_pagination.py

    from rest_framework import status
    from rest_framework.pagination import LimitOffsetPagination
    from rest_framework.response import Response
    
    class CustomPagination(LimitOffsetPagination):
    def get_paginated_response(self, data):
        return Response({
            "status": True,
            "code": status.HTTP_200_OK,
            'next': self.get_next_link(),
            'previous': self.get_previous_link(),
            'count': self.count,
            'results': data
        })
    

    在您看来,您需要做的就是调用两个函数,即 paginate_queryset 和您在分页类 get_paginated_response 中创建的一个。 “pagination_queryset”将查询集作为参数,然后将该结果传递给您的序列化程序,最后调用“get_paginated_response”,它将序列化数据作为参数并在结果返回响应中。

    page = self.paginate_queryset(query_set)
    serializer_class = <Your Serializer>(page, many=True,)
    return self.get_paginated_response(serializer_search_user.data)
    

    最后在“settings.py”中声明你的自定义序列化类。

    REST_FRAMEWORK = {
          'DEFAULT_PAGINATION_CLASS':'<your_app>.<your_peckage>.custom_pagination.CustomPagination',
          'PAGE_SIZE': 5
    }
    

    【讨论】:

    • 这是向我展示如何从应用程序正确导入分页类的一个答案。谢谢!
    【解决方案2】:

    您可以在视图集中使用自定义分页并在自定义视图上进行更改

    分页.py

    class OneByOneItems(pagination.PageNumberPagination):
        page_size = 2
    
        def get_paginated_response(self, data):
            return Response(OrderedDict([
                 ('lastPage', self.page.paginator.count),
                 ('countItemsOnPage', self.page_size),
                 ('current', self.page.number),
                 ('next', self.get_next_link()),
                 ('previous', self.get_previous_link()),
                 ('results', data)
             ]))
    

    views.py

    class LectionViewSet(viewsets.ReadOnlyModelViewSet):
        queryset = LectionCourse.objects.all().order_by('-created_at')
        serializer_class = LectionSerializer
    
        @list_route(methods=['get'], url_path='get-lections/(?P<pk>[^/]+)')
        def get_lection(self, request, pk):
            self.pagination_class = OneByOneItems
            queryset = self.filter_queryset(self.queryset.filter(course=pk))
            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)   
    

    序列化器.py

    class CourseSerializer(serializers.ModelSerializer):
        author = UserCreatorSerializer(many=True)
        project = ProjectSerializer(many=True)
    
        class Meta:
            model = Course
            fields = ('id', 'theme', 'author', 'project')
    
    
    class LectionSerializer(serializers.HyperlinkedModelSerializer):
        choose_course = CourseSerializer(source='course')
    
        class Meta:
            model = LectionCourse
            fields = ('id', 'title', 'video', 'preview_description', 'number', 'choose_course')
    

    【讨论】:

      【解决方案3】:

      对于 django_rest_framework 3.0.x(或以下):

      您可以直接扩展rest_framework.mixins.ListModelMixin,也可以实现类似的getlist 方法。

      当然generics.GenericAPIView也是需要的。

      def list(self, request, *args, **kwargs):
          queryset = self.filter_queryset(self.get_queryset())
          page = self.paginate_queryset(queryset)
          if page is not None:
              # get_paginaion_serializer will read your DEFAULT_PAGINATION_SERIALIZER_CLASS 
              # or view.pagination_serializer_class 
              # we will talk the two variable later
              serializer = self.get_pagination_serializer(page)
          else:
              serializer = self.get_serializer(queryset, many=True)
          return Response(serializer.data)
      

      如果你想配置它“global”,你可以在你的settings.py中配置

      REST_FRAMEWORK = {
          # ...
          'DEFAULT_PAGINATION_SERIALIZER_CLASS': 'YourCustomPaginationSerializer',
          # ...
      }
      

      如果您只想设置为特定视图:

      属性是pagination_serializer_class,而不是pagination_class

      class MyView(generics.GenericAPIView):
          pagination_serializer_class = YourCustomPaginationSerializerClass
      

      对于 django_rest_framework 3.1.x

      略有不同,您可以先查看文档。 3.1 Announcement , Pagination Docs

      您可以直接扩展rest_framework.mixins.ListModelMixin,也可以实现类似的get方法。

      当然generics.GenericAPIView也是需要的。

      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)
      

      如果你想配置它“global”,你可以在你的settings.py中配置

      REST_FRAMEWORK = {
          # ...
          'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
      
          # ...
      }
      

      如果您只想设置为特定视图:

      class MyView(generics.GenericAPIView):
          pagination_class = YourCustomPaginationClass
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-06
        • 2017-08-05
        • 2016-11-28
        • 1970-01-01
        • 1970-01-01
        • 2012-05-26
        • 1970-01-01
        • 2016-03-05
        相关资源
        最近更新 更多