2016-07-10 7 views
0

私はフィールドが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

をサブクラス化する必要が

return self.paginator.get_paginated_response(data) 

を返すget_paginated_response方法はAPIViewクラスとPageNumberPaginationページネーションとの結果をページ分割する方法の例である持っているGenericAPIViewがありますクラス:

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

ですから、ちょうどここでは、このミックスイン

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」オブジェクトは、あなたがGenericAPIView'はまだworking..Iは同じエラーを取得していない –

+0

何の属性」を持っていません。 ( –

+0

を修正'サブクラス化する必要があります申し訳ありませんget_paginated_response'' –

関連する問題