Django ORM:计算相关项的子集

时间:2010-10-11 02:25:25

标签: django django-models django-orm

我希望找到一种方法来使用相关项子集的计数来注释查询集。以下是我的模型的一部分:

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()

我正在制作一个查询集,用于注释一个人参加的俱乐部特定练习的数量。我已经可以通过查询Person.objects.all().annotate(Count('PracticeRecord'))

找到该人的实践总数

但是,我想在某种程度上注释一个人参加特定俱乐部的做法数量。

我更喜欢使用django ORM而不必使用原始SQL。

感谢。

2 个答案:

答案 0 :(得分:2)

  

但是,我想在某种程度上注释一个人参加特定俱乐部的做法数量。

让我们看看。

首先,找到特定的俱乐部。

club = Club.objects.get(**conditions)

接下来,过滤所有在该俱乐部练习过的人。

persons = Person.objects.filter(practicerecord__Practice__Club = club)

现在,用计数注释。

q = persons.annotate(count = Count('practicerecord'))

修改

我能够在我的测试设置中成功完成这项工作:Django 1.2.3,Python 2.6.4,Postgresql 8.4,Ubuntu Karmic。

PS :对字段使用小写名称是一个好主意。这使得使用双下划线(__)语法链字段变得更加容易。对于例如在您的情况下,Django会为每个practicerecord自动创建Person。当您尝试通过此字段访问PracticeRecord的其他字段时,您必须记住使用标题大小写。

如果您使用了小写名称,则可以写成:

persons = Person.objects.filter(practicerecord__practice__club = club)
#                                               ^^        ^^  

看起来更加统一。

PPS Count('practicerecord')(请注意小写)。

答案 1 :(得分:0)

我担心原始sql是唯一的选择。无论如何,如果你把它交给模特经理,那就不那么可怕了。