在模板中,我显示了项目(i)的前5个翻译。模板中处理以下逻辑:
more...
。 这是我提出的(功能)模板代码:
{% 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
查询是否可能更好,因为以后可以使用它并且可以(自动?)缓存?答案 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 %}
这使用两个查询而不是一个,但如果您发现它更清楚,您可能更喜欢它。实际上,额外的查询可能对性能没有影响。