jazzband / django-taggit

Simple tagging for django
https://django-taggit.readthedocs.io
BSD 3-Clause "New" or "Revised" License
3.34k stars 622 forks source link

How to enhance database performance and reduce the number of running SQL when using tags? #842

Closed Rahimz closed 1 year ago

Rahimz commented 1 year ago

I have a model like this:

class Product(models.Model):
    name = models.CharField(max_lenghth=50)
    category = models.ForeignKey(Category, on_delete=SET_NULL, null=True, blank=True)
    tags = TaggableManager(blank=True)

In my view:

def products(request):
    products = Product.objects.all().select_related('category')
    ...

for better performance I added select_related() for Category field then it runs just one Queryset. and in my template I have:

{% for product in products %}
    {{ product.category }} - {{ product }}
    {% if 'oldPrice' in product.tags.names %}<span>Old price<span>{% endif %}
{% endfor %}

when I add this if statement in my template, it hits the database every time that there is an oldPrice tag. When there are 100 products, it hits database 100 times. Is there any way like select_related() that helps me to reduce the numbers of executed SQLs?

jacoduplessis commented 1 year ago

In your view, use the following:

products = Product.objects.all().select_related('category').prefetch_related('tags')
rtpg commented 1 year ago

yes, prefetch_related is what you want for a many-to-many relationship in general.