views:

45

answers:

2

I am looking to find a way to annotate a queryset with the counts of a subset of related items. Below is a subset of my models:

class Person(models.Model):
    Name = models.CharField(max_length = 255)
    PracticeAttended = models.ManyToManyField('Practice',
                                              through = 'PracticeRecord')

class Club(models.Model):
    Name = models.CharField(max_length = 255)
    Slug = models.SlugField()
    Members = models.ManyToManyField('Person')

class PracticeRecord(PersonRecord):
    Person = models.ForeignKey(Person)
    Practice = models.ForeignKey(Practice)

class Practice(models.Model):
    Club = models.ForeignKey(Club, default = None, null = True)
    Date = models.DateField()

I'm looking to make a queryset which annotates the number of club specific practices attended by a person. I can already find the total number of practices by that person with a query of Person.objects.all().annotate(Count('PracticeRecord'))

However I would like someway to annotate the number of practices that a person attends for a specific club.

I would prefer something using the django ORM without having to resort to writing raw SQL.

Thanks.

+1  A: 
Manoj Govindan
WOW, that is cool and works perfectly ... I didn't know that if I filtered on a particular field then the aggregation would also be on the filtered rows. Out of curiosity do you know if this behavior is mentioned in the docs anywhere?
JudoWill
A: 

I'm afraid that raw sql is the only option here. Anyway it's not that scary and hard to manage if you put it to model manager.

Vladimir Sidorenko
@Vladimir: Strange. I was able to get it to work without resorting to Raw SQL. Tested in Django 1.2.3, Postgresql 8.4, Python 2.6.4, Ubuntu Karmic.
Manoj Govindan
Yes, there is way to annotate after filtering original queryset.I thought that task was to annotate practice records without filtering persons.
Vladimir Sidorenko