filter() with Q spanning ManyToMany relations return wrong results
|Reported by:||Waldemar Kornewald||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||queryset-refactor|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
I'll try to simplify our situation, so the code samples have nothing to do with our actual models. Currently, we use sqlite with Python 2.5 and Django queryset-refactor (trunk has similar problems, though).
We have models similar to these:
class Tag(Model): name = CharField(max_length=100) hits = ManyToManyField(Article, related_name='tags') class Category(Model): name = CharField(max_length=100) hits = ManyToManyField(Article, related_name='categories')
In our DB we have an Article object that has two tags ('taga' and 'tagb') and two categories ('cata' and 'catb').
Then we run the following query (find an Article that has both 'taga' and 'tagb' in the tags and/or categories):
Article.objects.filter( Q(categories__name__startswith='taga') \ | \ Q(tags__name__startswith='taga') \ , Q(categories__name__startswith='tagb') \ | \ Q(tags__name__startswith='tagb') \ ).distinct()
The query will not find the article (although it should). Now, if we swap the attribute accessing order (i.e., replace Q(categories__...) | Q(tags__...) with Q(tags__...) | Q(categories__...)) it'll work correctly.
In other words: Only the first attribute (categories__...) will allow for matching multiple times whereas the second attribute (tags__...) only allows for matching once. Note, this actually seems to only depend on the attribute order of the *last* Q group (in the snippet it's the Q pair for 'tagb').
Other example queries that work correctly with the above code snippet:
- 'cata' and 'catb'
- 'taga' and 'cata'
- 'cata' and 'taga' and 'catb'
Change History (5)
comment:1 Changed 6 years ago by mtredinnick
- Keywords qs-rf removed
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
- Triage Stage changed from Unreviewed to Accepted
- Version changed from SVN to queryset-refactor
comment:4 Changed 6 years ago by mtredinnick
- Resolution set to fixed
- Status changed from new to closed