Search code examples
djangomany-to-many

Django filter by many to many with exact same query


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


Solution

  • 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.