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.