Optimize django by eliminating duplicate querys

0

I am trying to get the number of products that each category has, but each category is in turn the father of other categories, so I want to know how many children that category has and their daughter categories, I have simplified the query to the maximum the next way, but in the django debug I keep showing up that I have 66 querys duplicated.

How can I eliminate these duplications?

With the first line of views.py, he managed to get the number of products in a category, but the problem is essentially to tell him to return me from the category and his daughters.

models.py

class Categoria(models.Model):
   nombre = models.CharField(max_length=200)
   slug = models.SlugField(max_length=100)
   padre = models.ForeignKey('self', blank=True, null=True, 
           related_name='cat_padre')
   pub_date = models.DateTimeField('date published', 
                                    auto_now_add=True)
   upd_date = models.DateTimeField('date updated', auto_now=True)

   def __str__(self):
       return self.nombre + ' ' + self.pais.iso

class Producto(models.Model):
   nombre = models.CharField(max_length=200)
   slug = models.SlugField(max_length=100)
   categoria = models.ForeignKey(Categoria)

views.py

cats = Categoria.objects.annotate(num_productos=Count('producto')).filter(pais__iso=pais, padre__isnull=True).order_by('-num_productos')

for c in cats:
     num_p = Producto.objects.filter(categoria__padre=c).count()
     c.num_productos += num_p

 contexto = {
    'categorias_padre': cats,
}

return render(request, 'web/pruebitas/product.html', contexto)

Django debug:

    
asked by Luis 26.12.2017 в 13:46
source

2 answers

0

I got the answer in English StackOverflow:

cats = Categoria.objects.annotate(
        num_productos=Count('cat_padre__producto', distinct=True) +
                      Count('producto', distinct=True)).filter(
        pais__iso=pais, padre__isnull=True).order_by('-num_productos')

link

    
answered by 28.12.2017 / 18:01
source
0

You should do a little optimization of queries in this case, if you already know in advance that you are going to consult the products of each of the categories, you could do select_related () since you have a relationship from one to many of the products to the categories, in this way you will be able to use the related products without executing more queries to the database, that is, you could do:

cats = Categoria.objects.select_related('producto').annotate(num_productos=Count('producto')).filter(pais__iso=pais, padre__isnull=True).order_by('-num_productos')

if you have many-to-one relationships or many-to-many relationships in other models, you could use prefetch_related () .

For more information you can read in the official documentation link

Greetings, I hope it solves you.

    
answered by 27.12.2017 в 17:49