对大量数据进行 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