2017-08-14 80 views
2

序章:如何在非通用视图/视图集中使用分页?

我已经看到了这个问题的不止一个帖子引起的:

,也应用在这里:

我已经由一个例如在SO文档统一我的答案,在上面的问题,但由于该文件将得到2017年8月8日关机,我将按照this widely upvoted and discussed meta answer的建议,并改变我例如一个自我回复的帖子。

当然,我很乐意看到任何不同的方法!


问:

我想用一个非通用视图/视图集中:在Django的REST框架项目(如APIView)。
当我读了pagination documentation:如果你使用的是通用的看法或viewsets

分页只自动执行。如果您使用的是常规的APIView,则需要自行调用分页API以确保您返回分页响应。举例来说,请参阅mixins.ListModelMixingenerics.GenericAPIView类的源代码。

,我还可以继续使用非通用视图/视图集中?
如何在其上实现分页?

回答

4

我们可以发现,而不需要一个解决方案来重新发明轮子:

  1. 让我们对generics分页是如何实现一看: django-rest-framework/rest_framework/generics.py
    这正是我们将使用我们的观点以及!

  2. 让我们假设我们有一个全球性的分页设置如以下:
    settings.py

    REST_FRAMEWORK = { 
        'DEFAULT_PAGINATION_CLASS': 
         'rest_framework.pagination.DESIRED_PAGINATION_STYLE', 
        'PAGE_SIZE': 100 
    } 
    
  3. 为了不臃肿我们的观点/视图集中的代码,我们可以创建自定义混入存储我们的分页代码:

    class MyPaginationMixin(object): 
    
        @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 
    
        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) 
    
        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) 
    
  4. 然后在views.py

    from rest_framework.settings import api_settings 
    from rest_framework.views import APIView 
    
    from my_app.mixins import MyPaginationMixin 
    
    class MyView(APIView, MyPaginationMixin): 
        queryset = OurModel.objects.all() 
        serializer_class = OurModelSerializer 
        pagination_class = api_settings.DEFAULT_PAGINATION_CLASS 
    
        # We need to override the get method to insert pagination 
        def get(self, request): 
         ... 
         page = self.paginate_queryset(self.queryset) 
         if page is not None: 
          serializer = self.serializer_class(page, many=True) 
          return self.get_paginated_response(serializer.data) 
    

现在我们有一个APIView与分页。

+0

'NoneType'对象没有属性'paginate_queryset'。即时通讯得到这个错误 – Thameem

+0

@Thameem没有一些代码来帮助你看看你做了什么有点困难......如果问题依然存在,考虑在这里提出一个问题。 –

+0

@感谢您的消息,我错过了这个响应返回self.get_paginated_response(serializer.data)。谢谢。它的工作现在 – Thameem