Opened 5 years ago
Last modified 5 years ago
#32549 closed Cleanup/optimization
Make `Q(Q(), ...)` equivalent to `Q(...)` — at Initial Version
| 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
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
This patch 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.
Note:
See TracTickets
for help on using tickets.