0

Due to the use of different serializers based on certain condition, i preferred to use APIView and override get function. I was content with APIView but now that i need pagination feature, I am having trouble to make it happen. That is why i want to switch to GenericAPIView but due to the use of multiple serializer I have no idea how can i do it.

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

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

            items = BaseItem.objects.dev_items().filter(owner=request.user)
            reply['data'].extend(ItemSerializer(items, many=True).data)

        except:
            reply['data'] = []
        return Response(reply, status.HTTP_200_OK)

UPDATE

Another way i tried is

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

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

            items = BaseItem.objects.dev_items().filter(owner=request.user)
            page = self.paginate_queryset(items)
            print ('page', page) # i always get None even when pass url as api/items?page=1
            if page is not None:
                reply['data'].extend(ItemSerializer(page, many=True).data)
            reply['data'].extend(ItemSerializer(items, many=True).data)

        except:
            reply['data'] = []
        return Response(reply, status.HTTP_200_OK)

    @property
    def paginator(self):
        """
        The paginator instance associated with the view, or `None`.
        """
        if not hasattr(self, '_paginator'):
            print (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.
        """
        print ('queryset', queryset)
        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)

No any way is working. Where have i done mistake?

pythonBeginner
  • 781
  • 2
  • 12
  • 27
  • Possible duplicate of [http://stackoverflow.com/questions/29071312/pagination-in-django-rest-framework-using-api-view](http://stackoverflow.com/questions/29071312/pagination-in-django-rest-framework-using-api-view). – hybor Apr 02 '17 at 08:05
  • @hybor Thanks for your reply. In my case there is use of two serializer so I do not have any idea on dealing this. – pythonBeginner Apr 02 '17 at 08:08
  • I tried that page = self.paginate_queryset(items) print ('page', page) if page is not None: reply['data'].extend(ItemSerializer(page, many=True).data) reply['data'].extend(ItemSerializer(items, many=True).data) but i get page as None all the time even when passing url as ?page=1 – pythonBeginner Apr 02 '17 at 08:24

2 Answers2

0

Do you really need two serializers ?
I think it may be a better choice to use a single Serializer with a custom to_representation:

class ItemSerializer(ModelSerializer):
   # Your fields

   def to_representation(self, instance):
       data = super(ItemSerializer, self).to_representation(instance)
       request = self.context.get('request')
       if request and instance.is_owned_by(request.user):
           return self.owner_to_representation(data, instance) # TO IMPLEMENT
       return data

Then, you can use a generic view. Your code is cleaner, simpler and you do not have to worry about the pagination:

class ItemList(generics.ListAPIView):
    serializer_class = ItemSerializer
    permission_classes = (permissions.IsAuthenticated,)

    def get_queryset(self):
        return BaseItem.objects.owned_items()| BaseItem.objects.dev_items()
pchiquet
  • 3,097
  • 1
  • 13
  • 15
0

This is as simple as importing your paginator, and calling it manually in the APIView.

class PollView(views.APIView):
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication,)
paginator = CustomPagination()

def get(self, request):
    queryset = Poll.objects.all()
    context = self.paginator.paginate_queryset(queryset, request)
    serializer = PollSerializer(context, many=True)
    return self.paginator.get_paginated_response(serializer.data)

NOTE: Custom class is not necessary, you can simply import from rest_framework.pagination at the top of your script. I created a CustomPagination class, inheriting from PageNumberPagination, so that I could set the page_size query, as per docs - http://www.django-rest-framework.org/api-guide/pagination/

Gary Burgmann
  • 193
  • 2
  • 5