1

I'm reading the beginnings of annotating and aggregating and I'm wondering which way is best to complete the following situation:

You want to count the number of authors for each book in a queryset. The tutorial suggests the following with annotate:

Book.objects.annotate(Count('authors'))

My question is, why do it this way when you can accomplish this with model instance methods:

#models.py
class Book(models.Model):
  authors = models.ManyToManyField(Author)

  def author_count(self):
    return self.authors.count()

#views.py
books = Book.objects.all()

#template.html
{% for book in books %}
  {{ book.author_count }}
{% endfor %}

Is one situation better than the other? Are there optimization benefits I'm missing?

qarthandso
  • 2,100
  • 2
  • 24
  • 40

1 Answers1

1

Because then you will have to query the model:

Books.objects.all()  # Or any other filter

and then you call count() - Once you do it for multiple objects(books) you will hit the DB for each book you call count() on!

When using annotate you will hit the DB only once, and get the result as a dict/list for all the books in the query.

Or Duan
  • 13,142
  • 6
  • 60
  • 65