summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Gaschignard <r.gaschignard@gmail.com>2018-02-07 12:09:43 +0900
committerTim Graham <timograham@gmail.com>2018-02-10 18:35:57 -0500
commitbf26f66029bca94b007a2452679ac004598364a6 (patch)
treecca99e7ec886b016f684c108d040da112434cc17
parent1a1264f1494976c562c7cb832fe47f3e1e765b8f (diff)
Fixed #29118 -- Fixed crash with QuerySet.order_by(Exists(...)).
-rw-r--r--django/db/models/expressions.py4
-rw-r--r--docs/releases/2.0.3.txt2
-rw-r--r--tests/expressions/tests.py14
3 files changed, 14 insertions, 6 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 2968e2cfee..b2a90c1a3f 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -1041,11 +1041,11 @@ class Exists(Subquery):
def __invert__(self):
return type(self)(self.queryset, negated=(not self.negated), **self.extra)
- def resolve_expression(self, query=None, **kwargs):
+ def resolve_expression(self, query=None, *args, **kwargs):
# As a performance optimization, remove ordering since EXISTS doesn't
# care about it, just whether or not a row matches.
self.queryset = self.queryset.order_by()
- return super().resolve_expression(query, **kwargs)
+ return super().resolve_expression(query, *args, **kwargs)
def as_sql(self, compiler, connection, template=None, **extra_context):
sql, params = super().as_sql(compiler, connection, template, **extra_context)
diff --git a/docs/releases/2.0.3.txt b/docs/releases/2.0.3.txt
index 277cab7573..252e51fcf0 100644
--- a/docs/releases/2.0.3.txt
+++ b/docs/releases/2.0.3.txt
@@ -15,3 +15,5 @@ Bugfixes
* Prioritized the datetime and time input formats without ``%f`` for the Thai
locale to fix the admin time picker widget displaying "undefined"
(:ticket:`29109`).
+
+* Fixed crash with ``QuerySet.order_by(Exists(...))`` (:ticket:`29118`).
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index 218e540bd9..c2e3fb391a 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -38,10 +38,8 @@ class BasicExpressionsTests(TestCase):
name="Foobar Ltd.", num_employees=3, num_chairs=4,
ceo=Employee.objects.create(firstname="Frank", lastname="Meyer", salary=20)
)
- cls.gmbh = Company.objects.create(
- name="Test GmbH", num_employees=32, num_chairs=1,
- ceo=Employee.objects.create(firstname="Max", lastname="Mustermann", salary=30)
- )
+ cls.max = Employee.objects.create(firstname='Max', lastname='Mustermann', salary=30)
+ cls.gmbh = Company.objects.create(name='Test GmbH', num_employees=32, num_chairs=1, ceo=cls.max)
def setUp(self):
self.company_query = Company.objects.values(
@@ -399,6 +397,14 @@ class BasicExpressionsTests(TestCase):
)
self.assertEqual(str(qs.query).count('JOIN'), 2)
+ def test_order_by_exists(self):
+ mary = Employee.objects.create(firstname='Mary', lastname='Mustermann', salary=20)
+ mustermanns_by_seniority = Employee.objects.filter(lastname='Mustermann').order_by(
+ # Order by whether the employee is the CEO of a company
+ Exists(Company.objects.filter(ceo=OuterRef('pk'))).desc()
+ )
+ self.assertSequenceEqual(mustermanns_by_seniority, [self.max, mary])
+
def test_outerref(self):
inner = Company.objects.filter(point_of_contact=OuterRef('pk'))
msg = (