user2349115
user2349115

Reputation: 1286

django AND on Q not working for many to many

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

Answers (1)

schillingt
schillingt

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

Related Questions