2017-04-01 72 views
0

我使用APIView獲取和發佈項目。
我想使用Django Rest Framework爲我的API實現分頁,但它不起作用。分頁不在DRF中工作APIView

我想每頁顯示10項,但當我做api/v1/items?page=1,我得到的所有項目,如果我只是做api/v1/items我得到一個空的列表。

這裏是我做了什麼:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 

class ItemsAPIView(APIView): 
    permission_classes = (permissions.IsAuthenticated,) 

    def get(self, request, format=None): 
     """ 
     Return a list of all items of this user. 
     """ 
     reply = {} 
     page = request.GET.get('page') 
     print ('page is', page) 
     try: 
      products = BaseItem.objects.owned_items().filter(owner=request.user) 
      reply['data'] = OwnedItemSerializer(products, many=True).data 

      items = BaseItem.objects.filter(owner=request.user) 
      paginator = Paginator(items, 1) 
      items_with_pagination = paginator.page(page) 
      if page is not None: 
       reply['data'].extend(ItemSerializer(items_with_pagination, many=True).data) 
      reply['data'].extend(ItemSerializer(items, many=True).data) 
+0

嘿,@pythonBeginner我想知道,你有沒有找到任何答案有幫助定義pagination_class? –

回答

-1

你可以讓你的生活變得更加簡單,只需使用一個ListView。通過重寫render_to_response,你可以讓它輸出json而不是HTML。它爲你做了所有的分頁。

from django.core import serializers 
from django.views.generic import ListView 

class MyListView(JSONResponseMixin, ListView): 
    model = models.BaseItem  
    paginate_by = 10 

    def render_to_response(self, context): 
     return JsonResponse(
      serializers.serialize("json", context), 
      **response_kwargs 
     ) 
+0

我有兩個序列化器用在我的APIView中,還有一個擴展函數。這是完全不同的。如果它只是使用model.objects.all(),我會更喜歡ListView。 – pythonBeginner

+0

然後在'get_context_data(self,** kwargs):' – kagronick

+0

中添加其他任何你需要的東西。你能以靜態框架的方式告訴我這個嗎? – pythonBeginner

0

非通用視圖和viewsets do not have pagination by default作爲Django的REST框架文件中規定:如果您使用的通用視圖或viewsets

分頁只自動執行。如果您使用的是常規的APIView,則需要自行調用分頁API以確保您返回分頁響應。舉例來說,請參閱mixins.ListModelMixingenerics.GenericAPIView類的源代碼。

我已經組成與代碼full example on enabling pagination on non generic views就如何實現這一目標:

class ItemsAPIView(APIView): 
    permission_classes = (permissions.IsAuthenticated,) 
    pagination_class = api_settings.DEFAULT_PAGINATION_CLASS 
    serializer_class = MyNewUnifiedSerializerClass 

    def get(self, request): 
     user_items = BaseItem.objects.filter(
          owner=request.user 
        ).distinct() 
     page = self.paginate_queryset(user_items) 

     if page is not None: 
      serializer = self.serializer_class(page, many=True) 
      return self.get_paginated_response(serializer.data) 

     serializer = self.get_serializer(user_items, many=True) 
     return Response(serializer.data) 

    # Now add the pagination handlers taken from 
    # django-rest-framework/rest_framework/generics.py 

    @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) 

對於更多的細節來看看example link provided

0

延長GenericAPIView,而不是APIViewGenericAPIView

0

分頁程序=無工作對我來說

> class NotesViewSet(viewsets.ModelViewSet):  
>  queryset = Notes.objects.all() 
>  serializer_class = NotesWriteSerializer 
>  paginator = None