Reputation: 14584
I have models that represent People and Books, which are joined via a through-model that can indicate their role (e.g. 'Author' or 'Editor'):
from django.db import models
class Person(models.Model):
name = models.CharField()
class Book(models.Model):
title = models.ChartField()
people = models.ManyToManyField('Person',
through='BookRole', related_name='books')
class BookRole(models.Model):
person = models.ForeignKey('Person', related_name='book_roles')
book = models.ForeignKey('Book', related_name='roles')
role_name = models.CharField()
And I have a Reading model that represents an occasion a Book was read:
class Reading(models.Model):
book = models.ForeignKey('Book')
start_date = models.DateField()
end_date = models.DateField()
I know how to get a list of Person
s ordered by the quantity Book
s associated with them:
from django.db.models import Count
from .models import Person
Person.objects.annotate(num_books=Count('books')) \
.order_by('-num_books')
But how can I get a list of Person
s ordered by the number of times their Book
s have been read (i.e. the number of Reading
s related to their Book
s)?
Upvotes: 0
Views: 327
Reputation: 308779
You can use the standard django double underscore notation:
Person.objects.annotate(num_readings=Count('books__reading')) \
.order_by('-num_readings')
See the docs on joins and aggregates for more info.
Upvotes: 4