2011-10-25 150 views
51

假設我有我的models.py是這樣的:Django過濾ManyToMany計數的模型?

class Hipster(models.Model): 
    name = CharField(max_length=50) 

class Party(models.Model): 
    organiser = models.ForeignKey() 
    participants = models.ManyToManyField(Profile, related_name="participants") 

現在在我的views.py我願做一個查詢這將獲取一個派對,那裏有超過0參與者的用戶。

事情是這樣的,也許:

user = Hipster.get(pk=1) 
hip_parties = Party.objects.filter(organiser=user, len(participants) > 0) 

什麼是做的最好的方式?

+21

+1僅用於創建「時髦」對象。太好笑了。 – jathanism

+2

+1爲偉大的課程,但也是一個簡潔的問題... – bhell

回答

92

如果這項工作,這是我將如何做到這一點。最好的方式可能意味着很多事情:最佳性能,最可維護性等等。因此,我不會說這是最好的方式,但我喜歡儘可能地堅持ORM功能,因爲它似乎更易於維護。

from django.db.models import Count 

user = Hipster.objects.get(pk=1) 
hip_parties = (Party.objects.annotate(num_participants=Count('participants')) 
          .filter(organiser=user, num_participants__gt=0)) 
+0

這是做這件事的另一種好方法,雖然不如選擇的答案簡潔。 – jathanism

+11

+1,「多於Y」,「少於X」全部在這裏覆蓋,不僅僅是null,它實際上回答了這個問題,「Django過濾ManyToMany計數的模型」 –

+3

這應該是真正被接受的答案。 – gregoltsov

28
Party.objects.filter(organizer=user, participants__isnull=False) 
Party.objects.filter(organizer=user, participants=None) 
+0

我不認爲這是最優雅的解決方案,但它適用於我的情況。如果有任何理智的做法,我仍會環顧四周。 – Ska

+0

這個解決方案有什麼優雅之處?這正是你要求的! :)答案並不完全清楚,但你會使用其中一種,而不是兩種。解決同一問題的兩種方法。 – jathanism

+0

如果可以直接參考號碼,當然會更優雅。 null與len()== 0不一樣,或者我錯過了什麼? – Ska

3

更容易exclude

# organized by user and has more than 0 participants 
Party.objects.filter(organizer=user).exclude(participants=None) 

也將返回不同的結果

0

從@虞姬-'Tomita'-富田應答所得出,我還添加了.distinct(」 id')來排除雙面打印記錄:

Party.objects.filter(organizer=user, participants__isnull=False).distinct('id') 

因此,每一方只列出一次。