Django在ManyToMany计数上过滤模型?
Posted
技术标签:
【中文标题】Django在ManyToMany计数上过滤模型?【英文标题】:Django filter the model on ManyToMany count? 【发布时间】:2011-12-14 14:19:39 【问题描述】:假设我的 models.py 中有这样的东西:
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)
最好的方法是什么?
【问题讨论】:
【参考方案1】:如果这行得通,我会这样做。
最好的方式可能意味着很多事情:最好的性能、最易维护等。因此我不会说这是最好的方式,但我喜欢尽可能地坚持 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))
【讨论】:
这是另一种好方法,尽管不如所选答案简洁。 +1, "more than Y", "less than X" 都在这里涵盖,而不仅仅是 null 实际回答了问题,“Django filter the model on ManyToMany count” 这比接受的答案更好地回答了 OPs 总结的问题,而不仅仅是您想要过滤零相关实例的情况。 @gregoltsov 5 年后,这是现在被接受的答案:)【参考方案2】:Party.objects.filter(organizer=user, participants__isnull=False)
Party.objects.filter(organizer=user, participants=None)
【讨论】:
我不认为这是最优雅的解决方案,但它适用于我的情况。如果有任何理智的方法,我仍然会环顾四周。 这个解决方案有什么不优雅的地方?这正是你所要求的! :) 答案并不完全清楚,但你会使用其中一个,而不是两者都使用。解决同一问题的两种方法。 @Ska 但这正是我的解决方案所做的。它允许您指定实际的数值。 @Yuji,当我这样做时,“participants__isnull=False”将导致重复条目。你有什么想法吗? @crossin 如果查询可能导致重复,请将.distinct()
附加到您的查询中。【参考方案3】:
exclude
更容易:
# organized by user and has more than 0 participants
Party.objects.filter(organizer=user).exclude(participants=None)
也返回不同的结果
【讨论】:
【参考方案4】:源自@Yuji-'Tomita'-Tomita 答案,我还添加了 .distinct('id') 以排除重复记录:
Party.objects.filter(organizer=user, participants__isnull=False).distinct('id')
因此,每一方只列出一次。
【讨论】:
以上是关于Django在ManyToMany计数上过滤模型?的主要内容,如果未能解决你的问题,请参考以下文章