1

Given a Django model with two M2M fields:

class Book(models.Model):
    name = models.CharField(max_length=300)
    authors = models.ManyToManyField(Author)
    publishers = models.ManyToManyField(Publisher)

And starting from a queryset of Authors:

authors = Author.objects.filter(...)

How can I annotate a count of the number of publishers (non-exclusive) the author has.... interacted with?

I can get the number of books the author has:

authors.objects.annotate(num_books=Count('book'))

But what I want is a count of the number of publishers for all books.

For example, if the data was like this:

Book | Authors | Publishers
B1     A1        P1, P2
B2     A2, A1    P1
B2     A2        P1, P2, P3
...

The resulting annotated counts would be:

Author |  Publishers
A1        3 (B1-P1, B1-P2, B2-P1)
A2        4 (B2-P1, B3-P1, B3-P2, B3-P3)
...
43Tesseracts
  • 4,617
  • 8
  • 48
  • 94

1 Answers1

0

Please try:

authors.annotate(num_publishers=Count('book__publishers')).values('id', 'num_publishers')

The result will be:

<Queryser [{'id': 1, 'num_publishers': 10}, {'id': 2, 'num_publishers': 2}, ... ]>
Sergey Pugach
  • 5,561
  • 1
  • 16
  • 31