Confused about this aggregation example from the docs

36 views
Skip to first unread message

Ankush Thakur

unread,
Jun 25, 2016, 10:11:44 AM6/25/16
to django...@googlegroups.com
On this page https://docs.djangoproject.com/en/1.9/topics/db/aggregation/ we have the following example of aggregation:

# All the following queries involve traversing the Book<->Publisher
# foreign key relationship backwards.

# Each publisher, each with a count of books as a "num_books" attribute.
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count('book'))
>>> pubs
[<Publisher BaloneyPress>, <Publisher SalamiPress>, ...]
>>> pubs[0].num_books
73

​The models used in this are as follows: 

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()

class Publisher(models.Model):
    name = models.CharField(max_length=300)
    num_awards = models.IntegerField()

class Book(models.Model):
    name = models.CharField(max_length=300)
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    rating = models.FloatField()
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    pubdate = models.DateField()

class Store(models.Model):
    name = models.CharField(max_length=300)
    books = models.ManyToManyField(Book)
    registered_users = models.PositiveIntegerField()

My question is: How come something like "Publisher.objects.annotate(num_books=Count('book'))" work? The name "book" is not defined as a reverse relationship (I think it should be accessible by "book_set"). 

How is this traversal working?

Regards,
Ankush Thakur

Tim Graham

unread,
Jun 28, 2016, 9:48:31 PM6/28/16
to Django users
'book' (the model name) is the default value of ForeignKey.related_name for the publisher field on Book.

class Book(models.Model):
    publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)

https://docs.djangoproject.com/en/stable/ref/models/fields/#django.db.models.ForeignKey.related_name

Ankush Thakur

unread,
Jul 7, 2016, 3:22:34 AM7/7/16
to Django users
Ah, that totally skipped my mind.

Thanks yet once again, Tim! :-)

Best,
Ankush
Reply all
Reply to author
Forward
0 new messages