[Answered ]-Why does the built-in "with" template tag in django result in duplicate queries

1👍

Why is this the case? Shouldn’t I be able to do things to that variable without it querying the database?

A QuerySet does not query the database, or at least not instantly when it is constructed. It is basically a promise to query the database when necessary, and .count() thus will query the database. You constructed one QuerySet, but this will make multiple queries.

A QuerySet can however cache the result if it is evaluated. If you use len(…) it does not count the records, or at least by a query, it loads the records, and then checks how many records have been loaded.

We can exploit this to work with the |length template filter [Django-doc], which will force evaluation of the QuerySet, and can be reused:

{% load custom_tags %}

<dl>
{% with authors=scenario|only_role:"AUTHOR" %}
  {% if authors|length %}
    <dt>Author{{ authors|length|pluralize }}</dt>
    {% for contribution in authors %}
      <dd>{{ contribution.contributor.name }}</dd>
    {% endfor %}
  {% endif %}
{% endwith %}
</dl>

The {% if authors|length %} can also be replaced with {% if authors %}, since a QuerySet has truthiness True if it contains at least one record.

Leave a comment