我可以在模板中迭代RelatedManager对象时减少查询吗?

时间:2011-03-12 14:24:31

标签: django

这是一个简单的假设。在我的Django应用程序中,我有Kit,KitSku和Sku的模型。 KitSku模型将Sku与套件相关联,并且还提供该套件中Sku的数量。在模板中我有类似的东西:

<!-- SELECT * FROM kitsku_table WHERE kit_id = <Kit.id> -->
{% for kitsku in kit.kitsku_set.all %}
  <!-- SELECT * FROM sku_table WHERE sku = <KitSku.sku> -->
  <div>{{ kitsku.sku.name }}</div>
{% endfor %}

现在,问题在于Django正在查询所有KitSku行,然后它在每个迭代的单独SQL查询中查询该for循环中的每个sku。

我可以通过kitsku_set.all()调用得到的SQL查询与Sku模型一起执行JOIN吗?

第一个查询需要更像:

SELECT * FROM kitsku_table k LEFT JOIN sku_table s ON (k.sku = s.sku) 
WHERE k.kit_id = <Kit.id>

2 个答案:

答案 0 :(得分:1)

在视图中执行此类逻辑,并使用select_related()直接查询外键

kitskus = Kit.objects.get(id=3).kitsku_set.select_related('sku')
return direct_to_template(request, "mytemplate.html", {'kitskus': kitskus})

答案 1 :(得分:1)

我只是复制一个类似问题的答案,但我认为这是一个更好的方法。

视图

newsletters = Newsletter.objects.prefetch_related('article_set').all()\
                    .order_by('-year', '-number')

return render_to_response('newsletter/newsletter_list.html',
                          {'newsletter_list': newsletters})

模板

{% block content %}
  {% for newsletter in newsletter_list %}
    <h2>{{ newsletter.label }}</h2>
    <p>Volume {{ newsletter.volume }}, Number {{ newsletter.number }}</p>
    <p>{{ newsletter.article }}</p>
    <ul>
    {% for a in newsletter.article_set.all %}
      <li>{{ a.title }}</li>
    {% endfor %}
    </ul>
  {% endfor %}
{% endblock %}

以下是完整的解释: 希望有所帮助

Iterating over related objects in Django: loop over query set or use one-liner select_related (or prefetch_related)