#16893 closed Bug (wontfix)
negation of Q object returns the same thing
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 1.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 (last modified by )
Not sure if this is a bug.
I was attempt to construct a Q object that wouldn't ever match anything (an API calls for a Q object to be returned, but certain situations call for nothing to be matched by it). I initially figured ~ Q() would do the trick, but that matches everything, just like a plain Q().
(I ended up using Q(pk__isnull=True), which is a hack but seems to be OK.)
Change History (7)
comment:1 by , 14 years ago
| Description: | modified (diff) |
|---|
comment:3 by , 14 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
Haven't dug into what would be required to make this work, but presuming it can be reasonably implemented this seems sensible.
comment:4 by , 9 years ago
For reference, it seems that the current behavior is tested (if not documented): https://github.com/django/django/blob/master/tests/queries/tests.py#L1692-L1694
Come to think of it, I'm not really sure how empty Q objects should be treated: what's the expected result of filter(Q()), filter(~Q()), exclude(Q()), or exclude(~Q())?
comment:5 by , 9 years ago
Ah, I see. filter() == all() == exclude(), all of which != none(). Keeping filter(~Q(...)) == exclude(Q(...))) certainly makes sense (if that's possible).
Maybe define a special singleton instance of Q that matches nothing?
comment:6 by , 9 years ago
To elaborate:
In django.db.models or someplace like it:
Nope = Q(pk__isnull=True)
Then in other code:
from django.db.models import Nope qs.filter(Nope) == qs.none() qs.exclude(Nope) == qs.all()
That still uses my pk__isnull=True hack, but that might be fine. Alternatively, the Q class itself could add some kind of explicit support for this.
I think these expressions should all be true: Nope | Q() == Q(), Nope & Q() == Nope, ~Nope == Q()
Nope isn't a great name, but it was the best I could do; Null is confusing with the SQL concept, None is taken, of course, and Nothing sounds like what filter(Nope) would return, not what it's passed. Is there a better word for unmatchable criteria?
comment:7 by , 5 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
As mentioned by Baptiste, the current behavior is tested and expected (IMO). Filtering by an empty condition Q() and negation of an empty condition ~Q() should return all objects, because negation of an empty condition is still an empty condition.
You can start a discussion on DevelopersMailingList if you don't agree.
comment:8 by , 5 years ago
| Triage Stage: | Accepted → Unreviewed |
|---|
Fixed formatting (you can use "preview" before submitting a ticket).