Reputation: 1286
Here's the model:
class ModelA:
title = charfield
m2m = foreignkey, relatedname='m2ms'
This is working:
ModelA.objects.filter(Q(title__icontains='a') & Q(title__icontains='b'))
So it returns all records whose titles contains both letters 'a' and 'b'.
Then same not working for many to many:
ModelA.objects.filter(Q(m2ms__id=1) & Q(m2ms__id=2))
ModelA m2ms list:
for x in ModelA.objects.all():
print x.m2ms.all().values_list('id', Flat=True)
#Output:
1,2,3
1,2
1
1,3,5
4,6,7
1,8
So, expected output of ModelA.objects.filter(Q(m2ms__id=1) & Q(m2ms__id=2)) should be records having these m2m ids: [1,2,3], [1,2]. But its not happening. Why ?
I cant use Q(m2ms__id__in=[1,2]) because it returns same even if I do __in=[1,2,3,4, infinite numbers]
Reason for using Q instead of filter is mentioned in this question - django filter on many to many along with Q
Upvotes: 3
Views: 447
Reputation: 13731
Read this section of the docs.
Particularly this paragraph:
To handle both of these situations, Django has a consistent way of processing filter() and exclude() calls. Everything inside a single filter() call is applied simultaneously to filter out items matching all those requirements. Successive filter() calls further restrict the set of objects, but for multi-valued relations, they apply to any object linked to the primary model, not necessarily those objects that were selected by an earlier filter() call.
I believe if you do ModelA.objects.filter(Q(m2ms__id__in=[1, 2]))
or ModelA.objects.filter(m2ms__id__in=[1, 2])
it will work as you expect it to.
Upvotes: 1