Django filter by many to many with exact same query

允我心安 提交于 2020-01-23 17:35:13

问题


Is there any way in django to filter objects with many to many relation by query set or ids list. Get query with exactly same values in many to many. model

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

views

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

expected: I am looking for filtered parents with exact same children in many to many field


回答1:


You can use chain filtering for that case.

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)

Or you can use lambda filtering:

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)

Or you can use Q() query:

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)

As a result you will get only Parent objects who have all those children in your list of ids only no less no more.




回答2:


I think this is what you're looking for:

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

UPDATE:

I think you need to unpack the child Ids and then do the following.

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

Please note that the order_by is necessary here as not having it would break the distinct operation. Note that you should replace the email with the field that's unique in your User model.

This should accomplish exactly what you're looking for.



来源:https://stackoverflow.com/questions/53911314/django-filter-by-many-to-many-with-exact-same-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!