13

How can I count related objects in Django (in less than N queries, where N is number of object).

To clarify, let's say I have tables A and B. Every B is connected to exactly one A. Approach I tried:

A.objects.select_related().filter(attr=val)
A[i].B_set.count()

Of course, for every A[i] I want to find out number of B objects Django executes one query.

So the question is - is there a way to optimize that?

1
  • What do you mean by "Every B is connected to exactly one A."? Does B has a foreign key field point to A? Or B has a OneToOne field pointing A? Commented Dec 12, 2018 at 9:38

3 Answers 3

21

I have not tried how many queries are executed, but the Django way should be using annotate(). For example:

from django.db.models import Count

q = A.objects.select_related('B').annotate(num_B=Count('B'))
print A[0].num_B
Sign up to request clarification or add additional context in comments.

2 Comments

This might be a stupid question, but I get the error saying the global name 'Count' is not defined when doing this.
nvm, found the answer: from django.db.models import Count
7

Since Django 2.0 Count() aggregate function accepts filter parameter, which allows applying additional restrictions on the related objects queryset. Works like this:

A.objects.select_related().annotate(
    total=models.Count('myrelated__pk', filter=Q(only_items='that-i-need'))
).all()

Comments

5

I have to answer my own question :) If object of A is queried something like this:

A.objects.select_related().filter(atrr=val).annotate(n_b=models.Count('B'))

This creates very long query, but at least there is just one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.