Opened 4 years ago
Last modified 4 years ago
#32549 closed Cleanup/optimization
Make `Q(Q(), ...)` equivalent to `Q(...)` — at Version 1
Reported by: | jonathan-golorry | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | Q objects, nested, empty |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Empty Q objects (Q()
or ~Q()
, etc) evaluate to False
, but Q(Q())
evaluates to True
. This interferes with the shortcut on logical operations involving empty Q objects and can lead to bugs when trying to detect empty operations.
def q_any(iterable): q = Q() for element in iterable: q |= element if q: return q return Q(pk__in=[]) Item.objects.filter(q_any()) # no items Item.objects.filter(q_any([Q()])) # no items Item.objects.filter(q_any([Q(Q())])) # all items
Patch https://github.com/django/django/pull/14127 removes empty Q objects from args
during Q object initialization.
This requires https://code.djangoproject.com/ticket/32548 in order to prevent a regression in logical operations between query expressions and empty Q objects.