2010-10-11 42 views
1

我正在尋找一種方法來用相關項目的子集計數來對註釋集進行註釋。下面是我的模型的一個子集: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

但是,我想要註釋一個人參加特定俱樂部的做法的數量。

讓我們來看看。

首先找到具體的俱樂部。

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

接下來,篩選所有在此俱樂部執業過的人。

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

現在,用count進行標註。

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

編輯

我是能夠成功地使這項工作在我的測試設置:Django的1.2.3,2.6.4的Python和PostgreSQL 8.4,Ubuntu的業報。

PS:這是一個好主意™使用小寫字母的名稱。這使得使用雙下劃線(__)語法來鏈接字段變得更加容易。對於例如在你的情況下,Django自動爲每個Person創建practicerecord。當您嘗試通過此字段訪問PracticeRecord的其他字段時,您必須記住使用標題大小寫。

如果你曾經使用小寫的名字,你可以寫:

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

看起來更均勻。

PPS:它是Count('practicerecord')(注意小寫)。

+0

哇,這很酷,完美的作品...我不知道,如果我過濾了一個特定的領域,那麼聚合也將在過濾行。出於好奇,你知道這種行爲是否在任何地方的文檔中都有提及? – JudoWill 2010-10-11 14:49:51

0

恐怕原生sql是唯一的選擇。無論如何,如果你把它交給模特經理,那不是那麼可怕和難以管理。

+0

奇怪。我能夠在不訴諸原始SQL的情況下運行它。經過Django 1.2.3,Postgresql 8.4,Python 2.6.4,Ubuntu Karmic測試。 – 2010-10-11 08:01:01

+0

是的,在過濾原始查詢集之後,可以對其進行註釋。我認爲該任務是在不過濾人員的情況下注釋練習記錄。 – 2010-10-12 05:46:45