对大量数据进行 Django 分页

Posted

技术标签:

【中文标题】对大量数据进行 Django 分页【英文标题】:Django pagination on a largeset of data 【发布时间】:2012-08-04 11:28:37 【问题描述】:

我正在使用模板来显示超过2000 行的表格。但是在此实施 django 分页会使它变得太慢,因为数据太多。什么是最好的方法来解决这个问题。或者如何我可以让分页每页加载 200 行并使页面更快。 如何让页面加载更快

   % extends "base/admin_base.html" %
   % load pagination_tags %




         % autopaginate response_dict.taggeddata 100 %
           <div align="right">% paginate %</div>
  <form action="/users/saveuser/" method="post">% csrf_token %
  <b>
        <table>

         <tr><td><font>*</font>Select Category group for tagging</td><td> 
         <select id="cgroup" onchange="getcategory('1');">
         <!--<option value="-1">Select Category group</option>   -->
         % for group in response_dict.categorygroup %
                  <option value="group.id">group.name</option> 
         % endfor %
         </select>  
         </td></tr>

        </table>
        </b>
        <table  id="box-table-a">
        <colgroup>
        <col class="vzebra-odd">
        <col class="vzebra-even">
        <col class="vzebra-odd">
        <col class="vzebra-even">
        <col class="vzebra-odd">
        <col class="vzebra-even">
        <col class="vzebra-odd">
        <col class="vzebra-even">
        </colgroup>
        <thead>
         <tr><th id="vzebra-comedy" scope="col">Field1</th><th id="vzebra-adventure" scope="col">Field2</th><th id="vzebra-comedy" scope="col">Field3</th><th id="vzebra-adventure" scope="col">Field4</th><th id="vzebra-comedy" scope="col">Field5</th><th id="vzebra-adventure" scope="col">Field6</th><th id="vzebra-comedy" scope="col">Tag</th><th id="vzebra-adventure" scope="col">Actions</th><thead></tr>
        <tbody>  
         % for td in response_dict.taggeddata %
           <tr id="td.id">
           <td >td.field1</td>
           <td>td.field2</td>
           <td>td.field3</td>
           <td>td.field4</td>
           <td>td.field5</td>
           <td>td.field6</td>
           <td class="tg">Select category</td>
           <td ><img src="/media/img/cancel.png"    onclick="delete_row('td.id')"></td>
           </tr>
         % endfor %
        </tbody>
        </table>
         <input type="button" value="Add" id="addbtn" onclick="validate();"/>

  </form>

【问题讨论】:

【参考方案1】:

我在 Django 中使用多达 400 万个数据集的分页。工作没有任何性能问题...

【讨论】:

你不明白这个问题。对于每个页面如果它查询400万行数据。那么就会有问题:) 那么我错过了什么?也许您可以快速解释为什么每次加载分页页面时我都应该经过 4m。我有点困惑 这就是我所相信的情况。每次我进入下一页时,我都会看到向服务器发出请求,并且每次都会获取所有 2000 行。如果你看到我的分页代码即,% autopaginate response_dict.taggeddata 100 % % paginate % 我不明白为什么会发生这种情况。但我们在猜测 - 这从来没有帮助。你安装了 django 调试工具栏了吗?如果没有,请获取它并检查发出的查询以及每个模块花费的时间。一旦我们证明了事实,我们就可以制定解决方案。 我刚刚再次检查了您的代码:您使用的是 django-pagination?如果我是对的:这是 Django 人的一个弃用项目。我建议改用核心功能...docs.djangoproject.com/en/dev/topics/pagination 如果您仍想使用 dj-pag,请先按照我上面的评论进行操作【参考方案2】:

使用基于类的视图, paginate_by :参见 django.views.generic.list.BaseListView 。 此外,如果性能很重要,请使用 ajax 并使用 json 将数据传递到前端。 另外我建议你使用 Model.objects.values_list()

类似这样的:

class MovieLandingJSON(JSONResponseMixin, BaseListView):
    """
    Movie landing page movie covers in json format.
    """
    paginate_by = 5
    context_object_name = 'movies'
    queryset = Movie.objects.all()
    values_list = ['id', 'title', 'slug']

    def get_queryset(self):
    """
    Filters  queryset on request
    """
        queryset = super(MovieLandingJSON, self).get_queryset()

        if self.values_list:
            queryset = queryset.values_list(*self.values_list)
        return queryset


from django.core.serializers import serialize
from django.utils.simplejson import dumps, loads, JSONEncoder
from django.db.models.query import QuerySet
from django.utils.functional import curry


class DjangoJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, QuerySet):
            # `default` must return a python serializable
            # structure, the easiest way is to load the JSON
            # string produced by `serialize` and return it
            return loads(serialize('json', obj))
        return JSONEncoder.default(self,obj)

dumps = curry(dumps, cls=DjangoJSONEncoder)


class JSONResponseMixin(object):
    """
    A mixin that can be used to render a JSON response.
    """
    response_class = HttpResponse

    def render_to_response(self, context, **response_kwargs):
        """
        Returns a JSON response, transforming QuerySet to json.
        """
        response_kwargs['content_type'] = 'application/json'
        return self.response_class(
            self.convert_queryset_to_json(context['object_list']),
            **response_kwargs
        )

    def convert_queryset_to_json(self, queryset):
        if self.values_list:
            return simplejson.dumps(list(queryset))
        else:
            return dumps(queryset)

【讨论】:

以上是关于对大量数据进行 Django 分页的主要内容,如果未能解决你的问题,请参考以下文章

关于分页

table大量数据无分页- virtualizedtableforantd

Elasticsearch:运用search_after来进行深度分页

我正在使用大量数据进行比较..有没有办法将数据分页到数据表

django面试四

如何在Django项目中组织大量页面的分页?