2011-10-25 99 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') 

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