Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-taggit: Is there a way to produce less db queries?

Say I have a model:

class Entry(models.Model):
    ...
    tags = TaggableManager()

When I iterate over Entry.objects.all() in a template, entry.tags.all produces one more query to the database. Is it possible to reduce queries number? Using something like select_related() (I know it won't work, since django-taggit uses manytomany relation, but I am sure there should be a way to select all entries with related tags in 1 hit)?

like image 810
dmrz Avatar asked Nov 05 '22 19:11

dmrz


1 Answers

From Django 1.4 onward, you can use prefetch_related to retrieve one-to-many relations on a queryset in a single query. Unfortunately this doesn't work brilliantly with django-taggit, because the 'tags' property is a manager rather than a true relation, and so prefetch_related can't make sense of it. Instead, you need to follow the tagged_items relation:

entries = Entry.objects.prefetch_related('tagged_items__tag')

You then need to go through some similar contortions in the template code to access the prefetched tags, because entry.tags.all will run another query rather than making use of the prefetch:

{% for tagged_item in entry.tagged_items %}
    <li>{{ tagged_item.tag.name }}</li>
{% endfor %}
like image 97
gasman Avatar answered Nov 13 '22 18:11

gasman