3

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

Community
  • 1
  • 1
user2349115
  • 1,288
  • 2
  • 17
  • 34

1 Answers1

1

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.

dhill
  • 3,327
  • 2
  • 19
  • 18
schillingt
  • 13,493
  • 2
  • 32
  • 34