开发者

Can I reduce queries while iterating a RelatedManager object within a template?

开发者 https://www.devze.com 2023-02-16 22:06 出处:网络
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

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)

0

精彩评论

暂无评论...
验证码 换一张
取 消