模板构造......它有效,但感觉很难看

时间:2017-03-08 14:16:38

标签: django django-models django-templates

在模板中,我显示了项目(i)的前5个翻译。模板中处理以下逻辑:

  • 如果有超过5个翻译:我修剪列表并显示一个 链接more...
  • 如果有1到5个翻译:我只是展示它们。
  • 如果没有翻译:我会显示一个添加翻译的链接。

这是我提出的(功能)模板代码:

{% if i.translation_set.all %}
    <ul>
    {% for t in i.translation_set.all|slice:"6" %}
        {% if forloop.counter < 6 %}
        <li>
            <a href="#">
                <i class="fa fa-play mr-2"></i>
                {{ t.language }}
                <i class="fa fa-commenting-o ml-1"></i>
            </a>
        </li>
        {% else %}
            <li>more...</li>
        {% endif %}
    {% endfor %}
    </ul>
{% else %}
    <a href="{% url 'view-item' i_id=i.id slug=i.slug %}">Add translation</a>
{% endif %}

以下是我对此代码的疑虑:

  • if i.translation_set.all执行了哪种查询?它是查询所有翻译还是停在1?
  • 使用相同的slice查询是否可能更好,因为以后可以使用它并且可以(自动?)缓存?
  • 查询6个项目感觉很难看,而只需要显示最多5个。还有另外一种方法可以告诉您有超过5个项目吗?

1 个答案:

答案 0 :(得分:3)

{% if i.translation_set.all %}

如果您之后没有循环查询集,那么您应该避免执行{% if i.translation_set.all %},因为它将从数据库中获取所有翻译。改进的方法是使用exists代替。

{% if i.translation_set.exists %}

更好的是,您可以使用{% with tag %}来获取切片的查询集。然后,您可以在if语句中使用切片查询集并循环遍历它。

{% with translations=i.translation_set.all|slice:"6" %}
{% if translations %}
<ul>
    {% for t in translations %}
    ...
    {% endfor %}
</ul>
...
{% endif %}
{% endwith %}

在切片中获取6个对象的替代方法是将计数作为单独的查询获取。然后,您可以将切片限制为5个对象。

{% with translation_count=i.translation_set.count %}
{% if translations_count %}
<ul>
    {% for t in translations|slice:"5" %}
    ...
    {% endfor %}
    {% if t.count > 5 %}
      <li>more...</li>
    {% endif %}
</ul>
...
{% endif %}
{% endwith %}

这使用两个查询而不是一个,但如果您发现它更清楚,您可能更喜欢它。实际上,额外的查询可能对性能没有影响。