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

50👍

The approach you are doing now will be heavily inefficient, because it will result in an 1+N number of queries. That is, 1 for the query of all your Newsletters, and then 1 for every single time you evaluate those n.article_set.all() results. So if you have 100 Newletter objects in that first query, you will be doing 101 queries.

This is an excellent reason to use prefetch_related. It will only result in 2 queries. One to get the Newsletters, and 1 to batch get the related Articles. Though you are still perfectly able to keep doing the zip to organize them, they will already be cached, so really you can just pass the query directly to the template and loop on that. :

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 %}
👤jdi

Leave a comment