Django使用完全相同的查询按多对多过滤

时间:2018-12-24 09:04:52

标签: django many-to-many

在django中是否可以通过查询集或id列表过滤具有多对多关系的对象。以许多相同的值获取查询。 模型

class Parent(models.Model):
    name = models.CharField(max_length=1000)
    children = models.ManyToManyField(Child, blank=True)

观看次数

def filter_parents(request):
    children = Child.objects.filter(id__in=[1,2,3])
    parents = Parent.objects.filter(child=child)
    return parents

预期: 我正在寻找很多领域中完全相同的孩子的过滤父母

2 个答案:

答案 0 :(得分:2)

在这种情况下,您可以使用链式过滤。

from django.db.models import Count

children_id_list = [1, 2, 3]
parents = Parent.objects.annotate(count=Count('children')).filter(count=len(children_id_list))

for child_id in children_id_list:
    parents = parents.filter(children__id=child_id)

或者您可以使用lambda过滤:

c_id_list = [1, 2, 3]
parents = Parent.objects.annotate(count=Count('children')).filter(count=len(children_id_list))
parents = reduce(lambda p, id: parents.filter(child=id), c_id_list, parents)

或者您可以使用Q()查询:

from django.db.models import Count, Q

children_id_list = [1, 2, 3]
parents = Parent.objects.annotate(count=Count('children')).filter(count=len(children_id_list))

query = Q()
for child_id in children_id_list:
    query &= Q(children__id=child_id)
parents = parents.filter(query)

结果,您将仅获得Parent个对象,这些对象的ID列表中的所有children都不少。

答案 1 :(得分:0)

我认为这是您想要的:

parents = Parent.objects.filter(children__id__in=[1,2,3])

更新:

我认为您需要unpack子ID,然后执行以下操作。

parents = Parent.objects.annotate(child_id=F('children__id'))
                        .filter(child__id__in=[1,2,3])
                        .order_by('email').distinct('email')

请注意,此处order_by是必需的,因为没有distinct会中断email操作。请注意,您应该用User模型中唯一的字段替换forEach

这应该可以完全满足您的需求。

相关问题