我需要过滤在ManyToMany关系中元素数量与条件匹配的对象。这是一些简化的模型:
Place(models.Model):
name = models.CharField(max_length=100)
Person(models.Model):
type = models.CharField(max_length=1)
place = models.ManyToManyField(Place, related_name="people")
我试图这样做:
c = Count(Q(people__type='V'))
p = Places.objects.annotate(v_people=c)
但这只会使.v_people
属性计算出人数。
答案 0 :(得分:4)
自python-2.0起,您可以为此使用Count(..)
function [Django-doc]的filter=...
参数:
Place.objects.annotate(
v_people=Count('people', filter=Q(people__type='V'))
)
因此,这将为该特定v_people
对象分配给type='V'
的人数为Place
。
另一种方法是首先.filter(..)
关系:
Place.objects.filter(
Q(people__type='V') | Q(people__isnull=True)
).annotate(
v_people=Count('people')
)
因此,我们在此过滤关系,以使我们允许people
拥有type='V'
或根本没有people
的关系(因为Place
可能具有否people
。然后我们计算相关模型。
这会生成一个查询,例如:
SELECT `place`.*, COUNT(`person_place`.`person_id`) AS `v_people`
FROM `place`
LEFT OUTER JOIN `person_place` ON `place`.`id` = `person_place`.`place_id`
LEFT OUTER JOIN `person` ON `person_place`.`person_id` = `person`.`id`
WHERE `person`.`type` = V OR `person_place`.`person_id` IS NULL