Reputation: 390
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
Upvotes: 1
Views: 3915
Reputation: 5669
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.
Upvotes: 6
Reputation: 1745
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.
Upvotes: 1