This is a hypothetical for simplicity. In my Django app I have models for Kit, KitSku, and Sku. The KitSku model associates a Sku with a Kit and 开发者_运维知识库also provides the quantity of that Sku in that kit. In the template I have something like:
<!-- 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 %}
Now, the problem here is that Django is querying all of the KitSku rows and then it queries each sku within that for loop in a separate SQL query for each iteration.
Can I make the SQL query resulting from the kitsku_set.all() call perform a JOIN with the Sku model?
That first query needs to be more like:
SELECT * FROM kitsku_table k LEFT JOIN sku_table s ON (k.sku = s.sku)
WHERE k.kit_id = <Kit.id>
Do this type of logic in the view, and use select_related() to directly query the foreign keys
kitskus = Kit.objects.get(id=3).kitsku_set.select_related('sku')
return direct_to_template(request, "mytemplate.html", {'kitskus': kitskus})
Im just copying an answer for a similar question, but i think this is a much better approach.
view
newsletters = Newsletter.objects.prefetch_related('article_set').all()\
.order_by('-year', '-number')
return render_to_response('newsletter/newsletter_list.html',
{'newsletter_list': newsletters})
template
{% 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 %}
Here is the complete explanation: Hopes it helps
Iterating over related objects in Django: loop over query set or use one-liner select_related (or prefetch_related)
精彩评论