【问题标题】:Django - queryset split to 4, causes lots of hits to the databaseDjango - 查询集拆分为 4,导致对数据库的大量命中
【发布时间】:2013-11-30 12:27:30
【问题描述】:

这是我的模板标签:

@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。但它似乎也对我的数据库造成了沉重的打击。首先它评估完整的查询集,然后每一列都有自己的评估,我该如何优化它?

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

【问题讨论】:

    标签: python django django-templates django-database


    【解决方案1】:

    在处理所有数据时,必须至少处理一个返回所有数据的select。要查询一次数据,您可以在第一步请求所有数据(评估查询集),然后在第二步用纯 python 拆分它(不打 DB):

    @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
    

    【讨论】:

      【解决方案2】:
      @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
      

      【讨论】:

      • 此拆分与 OP 使用的拆分不同;您可以使用i = (i + 1) % 4 删除if 条件
      【解决方案3】:

      你为什么不用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 %}
      

      【讨论】:

      • 刚刚注意到这个答案。这是一个有趣的方法。为什么有两个相同的if?我什么时候关闭
      • 抱歉,已修复。
      • 不,我仍然认为我不明白这一点。它每 4 个项目开始列表。我想要 4 个 div,而不是 queryset/4 个 div。编辑:完全迷路了,需要一点时间来测试它:]
      • 不,这不是我想要的。但很高兴知道有这个内置标签,谢谢。
      【解决方案4】:

      Django 提供了一些类来帮助您管理分页数据——即,通过“上一个/下一个”链接拆分到多个页面的数据:

      from django.core.paginator import Paginator
      

      【讨论】:

        猜你喜欢
        相关资源
        最近更新 更多
        热门标签