Q:

Following foreign keys in Django

I have a model that looks like this:
class Shelf(models.Model):
        name = models.CharField(max_length=20)

class Book(models.Model):
        shelf = models.ForeignKey(Shelf)
        name = models.CharField(max_length=20)

class Page(models.Model):
        book = models.ForeignKey(Book)
        name = models.CharField(max_length=20)

and I'd like to produce a list of shelves with a summary of what they contain:
  Shelf  | Books | Pages
------------------------
   Home  |   12  |  2000
  Office |   8   |  1300

I can count the number of books easily with book_set.count but this does not seem to extend further (thinking book_set.page_set.count). Something like sum([p.page_set().count for p in book_set.all()]) works, but is extremely slow.
Is there a good way to achieve this, or am I forced to generate infrequently and cache this information?

A:

If I understand you correctly, you want to find the total number of pages for each shelf. This is what aggregation does.
from django.db.models import Count
shelves = Shelf.objects.all().annotate(page_count=Count('book__page')

