Hi!
I made a Django app where the user can create an arbitrary filter using buttons, selects and inputs. The filter is represented in JSON format and later converted to a Django ORM query. The conversion code is based on the django.db.models.Q object, using & and | to combine the multiple filter rules to a single Q object that is passed to a Model.objects.filter.
It has been working for more than a year, but yesterday we found a case where it doesn’t: when we need to filter by multiple objects in the same ManyToMany relationship.
Using the example from the docs, with Publication and Article, I’m doing something equivalent to:
q = Q(publications__id=1) & Q(publications__id=2)
Article.objects.filter(q)
And the result is always None. I think it’s trying to find a publication with id==1==2, what is impossible.
The common workaround is to use multiple .filter calls:
Article.objects.filter(publications__id=1).filter(publications__id=2)
This also works with my models, but doesn’t seem a viable solution for my case, since mine is based on the Q object. Maybe I could have a special handling for the outer most filter rules, to use multiple .filter calls instead of combining Q objects, but these type of rules (ManyToMany relationship filtering) may appear in more deep levels of the JSON filter (inside other AND and OR rules). I would have to rewrite the entire conversion code to use only .filter and .exclude, instead of Q object, I’m not even sure it is possible…
The questions are:
- Is this an expected behavior? This ticket seems to state that yes. (but I’m not very convinced)
- How to reproduce the multiple
.filtercalls behavior using only Q objects?
Thanks for the attention!