首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用JsonResponse分页

用JsonResponse分页
EN

Stack Overflow用户
提问于 2018-02-28 18:05:03
回答 5查看 6.8K关注 0票数 13

我想在我的JsonResponse中添加分页。

我目前正在使用django.http.JsonResponse从弹性搜索API中生成json。我想添加一个分页功能,以便包括在内。我的代码如下:

代码语言:javascript
复制
class ResultQueryView(View):
    def get(self, request):
        resource_meta = request.GET.getlist("resource_meta")
        locations = request.GET.getlist("location")
        page = request.GET.get("page")
        logger.info("Got search query where resource_meta: {} and locations: {}".format(resource_meta, locations))
        results = resource_query(resource_meta, locations)
        resource_ids = [r["_id"] for r in results['hits']['hits']]
        resources = get_enriched_resources(request.user, Resource.objects.filter(internal_id__in=resource_ids))
        serialized = ResourceSerializer(resources, many=True)
        return JsonResponse({"resources": serialized.data})
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2019-02-18 21:28:00

使用Django的Paginator

代码语言:javascript
复制
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
代码语言:javascript
复制
class ViewPaginatorMixin(object):
    min_limit = 1
    max_limit = 10

    def paginate(self, object_list, page=1, limit=10, **kwargs):
        try:
            page = int(page)
            if page < 1:
                page = 1
        except (TypeError, ValueError):
            page = 1

        try:
            limit = int(limit)
            if limit < self.min_limit:
                limit = self.min_limit
            if limit > self.max_limit:
                limit = self.max_limit
        except (ValueError, TypeError):
            limit = self.max_limit

        paginator = Paginator(object_list, limit)
        try:
            objects = paginator.page(page)
        except PageNotAnInteger:
            objects = paginator.page(1)
        except EmptyPage:
            objects = paginator.page(paginator.num_pages)
        data = {
            'previous_page': objects.has_previous() and objects.previous_page_number() or None,
            'next_page': objects.has_next() and objects.next_page_number() or None,
            'data': list(objects)
        }
        return data

现在,使用ViewPaginatorMixin支持View分页。

代码语言:javascript
复制
class ResultQueryView(ViewPaginatorMixin, View):
    def get(self, request):
       // code
       serialized = ResourceSerializer(resources, many=True)
       return JsonResponse({"resources": self.paginate(serialized.data, page, limit)})
票数 13
EN

Stack Overflow用户

发布于 2019-02-14 08:37:09

一个简单的解决方案可以是在构建serialized.data之前对JsonResponse进行切片(甚至可以用预期页面的总n来注释结果,即math.ceil(len(serialized.data) / PAGE_SIZE)):

代码语言:javascript
复制
PAGE_SIZE = 10

start = page * PAGE_SIZE
stop = min(start + PAGE_SIZE, len(serialized.data))
#return JsonResponse({"resources": serialized.data})
return JsonResponse({"resources": serialized.data[start:stop]})

测试:

代码语言:javascript
复制
class FakeSerialized(object):
    def __init__(self):
        self.data = list(range(0,35))

serialized = FakeSerialized()
print('All data:', serialized.data)
PAGE_SIZE = 10

for page in range(0, 5):

    start = page * PAGE_SIZE
    stop = min(start + PAGE_SIZE, len(serialized.data))
    data = serialized.data[start:stop]

    print('Page %d:' % page, data)

结果:

代码语言:javascript
复制
$ python3 ./paginate.py
All data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34]
Page 0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Page 1: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Page 2: [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
Page 3: [30, 31, 32, 33, 34]
Page 4: []
票数 8
EN

Stack Overflow用户

发布于 2019-02-14 11:35:49

可以重写get_queryset()ListAPIView,以返回根据需要构造的查询集,然后使用视图的内建分页:

代码语言:javascript
复制
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination


class ResultQueryView(ListAPIView):
    serializer_class = ResourceSerializer
    # configure this according to your needs
    pagination_class = PageNumberPagination

    def get_queryset(self):
        resource_meta = self.request.GET.getlist("resource_meta")
        locations = self.request.GET.getlist("location")
        results = resource_query(resource_meta, locations)
        resource_ids = [r["_id"] for r in results['hits']['hits']]
        return Resource.objects.filter(internal_id__in=resource_ids))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49035909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档