Opened 9 months ago

Closed 9 months ago

#34786 closed Uncategorized (invalid)

Multiple Q objects in the same .filter() behave oddly with ManyToMany relationships

Reported by: Jon Janzen Owned by: nobody
Component: Database layer (models, ORM) Version: 4.2
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I found something odd, this may be intentional behavior (if undocumented, AFAICT) or might be covered by another bug report. If so, I apologize for the dupe.

Basically, I would have expected the following to behave the same, but they do not:

Test.objects.filter(Q(tags=1)).filter(Q(tags=2))
Test.objects.filter(Q(tags=1), Q(tags=2))

(Where Test is some model with a Many2Many relationship called "tags" and the model on the other end of "tags" has 2 objects with IDs 1 and 2)

In my testing, the first query returns an "and" of the results, that is, only Test objects that are tagged with BOTH Tag 1 and Tag 2, while the second query returns no results. Furthermore, Test.objects.filter(Q(tags=1) & Q(tags=2)) also returns no results.

I have a system that converts GitHub-like query expressions (e.g. "is:pr is:open author:bigfootjon") into Django ORM and it previously made a call like ModelToSearch.objects.filter(*q_expressions) until I hit this "bug" when I was adding support for searching via a ManyToMany field. Now I just loop over q_expressions and call .filter() repeatedly so I'm not blocked by this, but I thought it was odd. I checked the docs (https://docs.djangoproject.com/en/4.2/topics/db/queries/) and didn't see anything about this edge-case mentioned.

I've prepared a test-project that reproduces this behavior with instructions on how to show the weirdness: https://github.com/bigfootjon/djangoqbugreport

(In that repo I specify testing against Django 4.2.4, but this also reproduces on Django 5.0 at commit 517d3bb4dd17e9c51690c98d747b86a0ed8b2fbf aka Django==5.0.dev20230819082943)

I'm not sure whether to classify this as a bug or not, but if it is not a bug I think it should be documented (somehow, I don't quite understand the problem well enough myself to document it).

I'm afraid I don't quite have the ORM terminology to express this bug clearly so I apologize if this isn't clear in any way, I'm happy to answer questions.

Change History (1)

comment:1 by Mariusz Felisiak, 9 months ago

Resolution: invalid
Status: newclosed

This is not strictly related with Q() objects and it's a documented behavior (check out #27936).

Note: See TracTickets for help on using tickets.
Back to Top