summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2018-03-08 02:06:19 -0500
committerTim Graham <timograham@gmail.com>2018-03-08 13:30:41 -0500
commit277ed072094ad87fc6b2c4669f21d43b1f39043c (patch)
treedef44c83f6d3919a41d5c027ee693418d80c063d
parentfd9398816e14554b52362f1152349da832fab4b1 (diff)
Fixed #29195 -- Fixed Exists.output_field resolution on single-valued queries.
The Subquery class which Exists inherits from defaulted to using single-valued querie's field if no output_field was explicitly specified on initialization which was bypassing the Exists.output_field defined at the class level. Moving Subquery's dynamic output_field resolution to _resolve_output_field should make sure the fallback logic is only performed if required. Regression in 08654a99bbdd09049d682ae57cc94241534b29f0. Thanks Oli Warner for the detailed report.
-rw-r--r--django/db/models/expressions.py7
-rw-r--r--docs/releases/2.0.4.txt3
-rw-r--r--tests/expressions/tests.py4
3 files changed, 11 insertions, 3 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 4ce869d80a..44c687ffa7 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -960,10 +960,13 @@ class Subquery(Expression):
def __init__(self, queryset, output_field=None, **extra):
self.queryset = queryset
self.extra = extra
- if output_field is None and len(self.queryset.query.select) == 1:
- output_field = self.queryset.query.select[0].field
super().__init__(output_field)
+ def _resolve_output_field(self):
+ if len(self.queryset.query.select) == 1:
+ return self.queryset.query.select[0].field
+ return super()._resolve_output_field()
+
def copy(self):
clone = super().copy()
clone.queryset = clone.queryset.all()
diff --git a/docs/releases/2.0.4.txt b/docs/releases/2.0.4.txt
index dcfcc42f47..222b2360a5 100644
--- a/docs/releases/2.0.4.txt
+++ b/docs/releases/2.0.4.txt
@@ -9,4 +9,5 @@ Django 2.0.4 fixes several bugs in 2.0.3.
Bugfixes
========
-* ...
+* Fixed a crash when filtering with an ``Exists()`` annotation of a queryset
+ containing a single field (:ticket:`29195`).
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index 0286a956e6..7453838839 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -417,6 +417,10 @@ class BasicExpressionsTests(TestCase):
outer = Employee.objects.annotate(is_point_of_contact=Exists(inner))
self.assertIs(outer.exists(), True)
+ def test_exist_single_field_output_field(self):
+ queryset = Company.objects.values('pk')
+ self.assertIsInstance(Exists(queryset).output_field, models.BooleanField)
+
def test_subquery(self):
Company.objects.filter(name='Example Inc.').update(
point_of_contact=Employee.objects.get(firstname='Joe', lastname='Smith'),