Reputation: 2096
Suppose I have a model called X
, X
contains a field called Ys
, a many-to-many field for a class Y
.
If I have a list of multiple instances of the model Y
, how to filter for X
s that have the field Ys
that is a superset of my list?
Example:
I have 3 X
objects here:
x1.Ys
= [y1
, y3
, y4
]
x2.Ys
= [y1
, y2
, y3
]
x3.Ys
= [y1
, y2
]
items_list: [y1
, y2
]
I want to write X.objects.filter(xxx=items_list)
and get x2
, and x3
but not x1
.
What should I write in place of xxx
?
Upvotes: 0
Views: 191
Reputation: 2061
Use union
and difference
on the 2 set and that will work for you :
x1.Ys = set([y1, y3, y4])
x2.Ys = set([y1, y2, y3])
x3.Ys = set([y1, y2])
items_list = set.union(x2.Ys, x3.Ys).difference(x1.Ys)
This will merge x2
and x3
and remove all element from x1
And now easy query :
X.objects.filter(Ys__in=items_list)
Upvotes: 1
Reputation: 7330
You can use __in
.
For example.
X.objects.filter(Ys__in=items_list)
EDIT: You can try this using annotation
from django.db.models import Count
list_count = len(items_list)
X.objects.filter(YS__in=items_list).annotate(count_ys=Count('Ys')).filter(count_ys=list_count)
Upvotes: 3