Opened 9 years ago

Closed 8 years ago

#26517 closed Bug (fixed)

Empty Querset Using Empty Queryset in ExpressionWrapper

Reported by: Sven R. Kunze Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Sven R. Kunze)

We use the ExpressionWrapper + annotate to annotate specific boolean values to all queried instances like this (minimal working example):

editable_ones = ..... # another queryset
result = MyModel.objects.annotate(editable=ExpressionWrapper(Q(pk__in=editable_ones), output_field=BooleanField())

As soon as editable_ones is empty, result is also empty. Reading the docs, I guess this is not desired behavior (https://docs.djangoproject.com/en/1.9/ref/models/querysets/#annotate).

Change History (9)

comment:1 by Sven R. Kunze, 9 years ago

Description: modified (diff)

comment:2 by Sven R. Kunze, 9 years ago

I did some further analysis:

MyModel.objects.annotate(editable=ExpressionWrapper(Q(pk__in=MyModel.objects.none()), output_field=BooleanField())
MyModel.objects.annotate(editable=ExpressionWrapper(Q(pk__in=MyModel.objects.filter(pk=-1)), output_field=BooleanField())

Both results differ.

MyModel.objects.none() forces the outer query to return an empty QuerySet.

comment:3 by Simon Charette, 9 years ago

Triage Stage: UnreviewedAccepted
Version: 1.8master

Related to or duplicate of both #26430 and #26433.

comment:4 by Simon Charette, 8 years ago

Has patch: set

comment:5 by Josh Smeaton, 8 years ago

FYI ExpressionWrapper was never meant to be used to wrap up Q() objects. Q() are not really expressions themselves, they just implement some of the same API internally.

You're much better off using Case Expressions https://docs.djangoproject.com/en/1.9/ref/models/conditional-expressions/ for this use case:

MyModel.objects.annotate(editable=Case(When(pk__in=[editable], then=1), default=0, output_field=BooleanField()) )

comment:6 by Tim Graham, 8 years ago

Patch needs improvement: set

comment:7 by Johannes Dollinger, 8 years ago

Patch needs improvement: unset

comment:8 by Tim Graham, 8 years ago

Triage Stage: AcceptedReady for checkin

comment:9 by Tim Graham <timograham@…>, 8 years ago

Resolution: fixed
Status: newclosed

In c002a0d3:

Fixed #26517 -- Fixed ExpressionWrapper with empty queryset.

Note: See TracTickets for help on using tickets.
Back to Top