2016-07-10 58 views
0

我在其中我試圖獲取所有具有update_ts場比product_sync_ts從時間服務器更大的Product表產品中的Django項目工作,但由於產品數量較大此需要大量的時間來獲取所有數據。我還將當前的時間戳與數據一起返回。現在我想對結果進行分頁。在串行器使用分頁的Django

我以前的代碼:

Views.py

@api_view(['GET']) 
def productlist(request, format=None): 
    product_sync_ts = request.GET.get(
      'product_sync_ts', None) 
    if product_sync_ts: 
     product =Product.objects.filter(
      update_ts__gt=product_sync_ts) 
     ) 
     serializer = SyncedProductSerializer(
      instance={'products': product}) 
     return response(serializer.data) 
    else: 
     content = {'details': "Bad Request"} 
     raise APIException400(request, content) 

serializer.py

class SyncedProductSerializer(serializers.Serializer): 
    product_sync_ts = serializers.SerializerMethodField(
     method_name='get_current_ts' 
    ) 
    products = ProductSerializer(many=True, read_only=True) 

    class Meta: 
     fields = ('products', 'product_sync_ts') 

    def get_current_ts(self, obj): 
     product_sync_ts = datetime.utcnow().isoformat(' ') 
     return product_sync_ts 




class ProductSerializer(serializers.ModelSerializer): 
    image_url = serializers.SerializerMethodField(
     method_name='change_image_url' 
    ) 

    class Meta: 
     model = Product 
     fields = (
      'id', 
      'name', 
      'unit', 
      'price', 
      'image_url' 
     ) 

    def change_image_url(self, obj): 
     return ''.join([ 
      CDN_URL, str(obj.image_url) 
     ]) if str(obj.image_url) else None 

如何我試圖修改它分頁:

Views.py

class PaginatedProductList(APIView): 

    def get(self, request, format=None): 
     product_sync_ts = request.GET.get(
      'product_sync_ts', None) 
     if product_sync_ts: 
      product = GrProduct.objects.filter(
       update_ts__gt=product_sync_ts 
      ) 
      paginator = Paginator(product, 1000) 
      page = request.GET.get('page') 
      try: 
       product = paginator.page(page) 
      except PageNotAnInteger: 
       product = paginator.page(1) 
      except EmptyPage: 
       product = paginator.page(paginator.num_pages) 

      serializer = SyncedProductSerializer(
       instance={'products': product}) 
      return Response(serializer.data) 
     else: 
      content = {'details': "Bad Request"} 
      raise APIException400(request, content) 

這是工作的罰款,我得到分頁結果,但問題是,我不能到下一個和以前的頁面信息發送到客戶端。客戶端無法知道什麼是有效(非空)頁數。

有人可以建議我如何修改我的代碼,以便這樣做。

回答

2

下面是一個例子,如何進行分頁與APIView類和PageNumberPagination分頁結果等級:

from rest_framework.views import APIView 
from rest_framework.pagination import PageNumberPagination 

class ProductList(APIView, PageNumberPagination): 
    # number of items per page by default 
    page_size = 1000 
    # max number of items per page 
    max_page_size = 1000 

    def get_queryset(self): 
     product_sync_ts = self.request.GET.get('product_sync_ts', None) 
     if product_sync_ts: 
      products = GrProduct.objects.filter(update_ts__gt=product_sync_ts) 
      return self.paginate_queryset(products, self.request) 

     raise APIException400(request, {'details': "Bad Request"}) 

    def get(self, request): 
     products = self.get_queryset() 
     serializer = SyncedProductSerializer(instance={'products': products}) 
     return self.get_paginated_response(serializer.data) 

DRF - PageNumberPagination配置您的分頁

+0

感謝它像一個魅力:) –

+0

也如何添加page_size和current_page_number隨着下一個和以前? –

+0

我想自定義get_paginated_response方法,但我不確定我是否正確地執行該操作 –

2

GenericAPIView具有get_paginated_response方法,它返回

return self.paginator.get_paginated_response(data) 

所以你只需要繼承這個密新

from rest_framework.generics import GenericAPIView 

class PaginatedProductList(GenericAPIView): # Fixed 

    def get(self, request, format=None): 
     product_sync_ts = request.GET.get(
      'product_sync_ts', None) 
     if product_sync_ts: 
      product = GrProduct.objects.filter(
       update_ts__gt=product_sync_ts 
      ) 
      paginator = Paginator(product, 1000) 
      page = request.GET.get('page') 
      try: 
       product = paginator.page(page) 
      except PageNotAnInteger: 
       product = paginator.page(1) 
      except EmptyPage: 
       product = paginator.page(paginator.num_pages) 

      serializer = SyncedProductSerializer(
       instance={'products': product}) 
      return paginator.get_paginated_response(serializer.data) # <- here it is 
     else: 
      content = {'details': "Bad Request"} 
      raise APIException400(request, content) 
+0

它說'AttributeError的:「PaginatedProductList」對象有沒有屬性「get_paginated_response'' –

+0

對不起,你需要繼承'GenericAPIView'固定 –

+0

仍然沒有working..I我得到了同樣的錯誤: ( –