[Django] #34786: Multiple Q objects in the same .filter() behave oddly with ManyToMany relationships

32 views
Skip to first unread message

Django

unread,
Aug 20, 2023, 1:13:09 AM8/20/23
to django-...@googlegroups.com
#34786: Multiple Q objects in the same .filter() behave oddly with ManyToMany
relationships
-------------------------------------+-------------------------------------
Reporter: Jon | Owner: nobody
Janzen |
Type: | Status: new
Uncategorized |
Component: Database | Version: 4.2
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
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:

{{{#!python
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.

--
Ticket URL: <https://code.djangoproject.com/ticket/34786>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 20, 2023, 8:40:03 AM8/20/23
to django-...@googlegroups.com
#34786: Multiple Q objects in the same .filter() behave oddly with ManyToMany
relationships
-------------------------------------+-------------------------------------
Reporter: Jon Janzen | Owner: nobody
Type: Uncategorized | Status: closed
Component: Database layer | Version: 4.2
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => invalid


Comment:

This is not strictly related with `Q()` objects and it's a
[https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-
valued-relationships documented] behavior (check out #27936).

--
Ticket URL: <https://code.djangoproject.com/ticket/34786#comment:1>

Reply all
Reply to author
Forward
0 new messages