[Fixed]-Django Rest Framework Paging

0👍

I got your first example working- to me it was clearer and more basic. All I did was add “.object_list” to stop the “is not JSON serializable” error.

This is your answer with my tiny tweak:

class WardrobeListView(APIView):

    renderer_classes = (JSONRenderer, )

    def get(self, request, *args, **kwargs):

        filters = {}
        for key, value in request.GET.items():
            key = key.lower()
            if key in wardrobematch:
                lookup, val = wardrobematch[key](value.lower())
                filters[lookup] = val

        qset = (
            Analytic.objects
            .filter(like=True,**filters)
            .order_by('-updated',)
            # .distinct('product_id',)
            .values('product_id', 'product__name', 'product__brand', 'product__store__store_name', 'product__variation__image__image', 'product__variation__price__price',)
    )
        paginator = Paginator(qset, 2) # Show 25 items per page

        page = request.GET.get('page')
        try:
            qset = paginator.page(page)
        except PageNotAnInteger:
             # If page is not an integer, deliver first page.
            qset = paginator.page(1)
        except EmptyPage:
             # If page is out of range (e.g. 9999), deliver last page of results.
            qset = paginator.page(paginator.num_pages)

        return Response(qset.object_list)
👤Ycon

1👍

When using regular ApiView, you should call the pagination API yourself, it will not perform pagination automatically.

I have created a pagination and a serializer mixim. I’m not sure it is best method, but it worked for me.

class SerializerMixim(object):

    def serialize_object(self,obj):
        """Serilize only needed fields"""
        return NotImplementedError


class PaginationMixim(object):

    _serializer = None

    def paginate(self,queryset,num=10):
        page = self.request.GET.get('page')
        paginator = Paginator(queryset, num)
        try:
            queryset = paginator.page(page)
        except PageNotAnInteger:
            queryset = paginator.page(1)
        except EmptyPage:
            queryset = paginator.page(paginator.num_pages)
        count = paginator.count
        previous = None if not queryset.has_previous() else queryset.previous_page_number()
        next = None if not queryset.has_next() else queryset.next_page_number()
        if self._serializer:
            objects = self._serializer(queryset.object_list,many=True).data
        else:
            objects = [self.serialize_object(i) for i in queryset.object_list]

        data = {'count':count,'previous':previous,
                 'next':next,'object_list':objects}
        return Response(data)

    def serialize_object(self,obj):
        return {'id':obj.pk}


class WardrobeListView(APIView,PaginationMixim,SerializerMixim):

    renderer_classes = (JSONRenderer, )
    #_serializer = AnalyticSerializer
    def get(self, request, *args, **kwargs):

        filters = {}
        for key, value in request.GET.items():
            key = key.lower()
            if key in wardrobematch:
                lookup, val = wardrobematch[key](value.lower())
                filters[lookup] = val

        qset = (
            Analytic.objects
            .filter(like=True,**filters)
            .order_by('-updated',)
            # .distinct('product_id',)


        return self.paginate(qset)

    def serialize_object(self,obj):
        return obj.serilized

then you need to create a propery for Analytic model like,

class Analytic(models.Model):
    .....

    @property
    def serilized(self):

        summary = {
            'id':self.product.id,
            'image':self.product.name,
            .......
        }
        return summary

this will also work with django rest serializers

👤Anoop

Leave a comment