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 jonathan-golorry)

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.

Change History (1)

comment:1 by jonathan-golorry, 4 years ago

Description: modified (diff)
Has patch: set
Note: See TracTickets for help on using tickets.
Back to Top