Django - 查询集拆分为4,导致数据库的大量命中

时间:2013-11-17 10:02:27

标签: python django django-templates django-database

这是我的模板标签:

@register.filter
def split_to_4_columns(queryset):
    split = int(ceil(queryset.count()/4.))
    columns = list()
    for i in range(4):
        columns.append(queryset[i*split:(i+1)*split])
    return columns

这是我在模板中的伪用法:

{% for column in queryset|split_to_4_columns %}
<div class="list">
    {% for object in column %}
    <a href="{{ object.get_absolute_url }}" class="item">{{ object }}</a>
    {% endfor %}
</div>
{% endfor %}

它基本上将我的长查询集(几百个对象)拆分为4列,以便更好地进行html演示。但它似乎也在我的数据库上受到重创。首先,它评估完整的查询集,然后每列都得到它自己的评估,我该如何优化它?

我正在使用缓存,但我仍然想知道如何在比缓存更低的级别上优化缓存。

4 个答案:

答案 0 :(得分:2)

在处理所有数据时,必须至少处理一个select返回所有数据。要查询一次数据,您可以在第一步请求所有数据(评估查询集),然后在第二步将其拆分为纯python(不是命中数据库):

@register.filter
def split_to_4_columns(queryset):
    values = list(queryset.all())
    split = int(ceil(len(values)/4.))
    columns = [values[i*split:(i+1)*split] for i in range(4)]
    return columns

答案 1 :(得分:1)

@register.filter
def split_to_4_columns(queryset):
    i = 0
    columns = [[],[],[],[],]
    for item in queryset:
        columns[i].append(item)
        if i == 3:
            i = 0
        else:
            i = i + 1

    return columns

答案 2 :(得分:1)

为什么不使用divisibleby

{% for object in queryset %}
 {% if forloop.counter|divisibleby:"4" %}
    <div class="list">
 {% endif %}
       <a href="{{ object.get_absolute_url }}" class="item">{{ object }}</a>
 {% if forloop.counter|divisibleby:"4" %}
    </div>
 {% endif %}
{% endfor %}

答案 3 :(得分:0)

Django提供了一些类来帮助您管理分页数据,即通过“上一页/下一页”链接分为几页的数据:

from django.core.paginator import Paginator