Django Rest框架分页

时间:2016-01-16 18:21:08

标签: django django-rest-framework

我正在尝试让我的API每页最多返回10个。这有助于我无限加载。 API网址将是我尝试看起来像这样:

www.mysite.com/api/test/?user=5&page=1

然而,这不起作用。

我已经跟随官方docs here without成功。

我只修改了两个文件,settings.py& rest_views.py。

settings.py -

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
}

rest_views.py -

from django.core.paginator import Paginator

...

wardrobematch = {
    'user': lambda x: ('user__pk', x)  
}

class WardrobeListView(APIView):

    renderer_classes = (JSONRenderer, )
    paginate_by = 10
    paginate_by_param = 'page_size'
    max_paginate_by = 100

    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',)
        )

        return Response(qset)

2 个答案:

答案 0 :(得分:1)

使用常规ApiView时,您应该自己调用分页API,它不会自动执行分页。

我创建了一个分页和一个序列化程序mixim。我不确定这是最好的方法,但它对我有用。

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

然后你需要为分析模型创建一个属性,比如

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

    @property
    def serilized(self):

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

这也适用于django rest serializers

答案 1 :(得分:0)

我得到了你的第一个例子,对我来说它更清晰,更基本。我所做的只是添加“.object_list”来阻止“不是JSON序列化”错误。

这是我的微小调整的答案:

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)
相关问题