diff options
| author | Simon Charette <charette.s@gmail.com> | 2018-03-08 02:06:19 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2018-03-08 14:06:10 -0500 |
| commit | 0fd21febe7b3969460e3e6f17bfedc63529f194b (patch) | |
| tree | d828bd9819e9a44999a36bad56dd609de55df111 | |
| parent | 8d3bd724ab996078a570dd736b85a8ad5b317f97 (diff) | |
[2.0.x] 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.
Backport of 277ed072094ad87fc6b2c4669f21d43b1f39043c from master
| -rw-r--r-- | django/db/models/expressions.py | 7 | ||||
| -rw-r--r-- | docs/releases/2.0.4.txt | 3 | ||||
| -rw-r--r-- | tests/expressions/tests.py | 4 |
3 files changed, 11 insertions, 3 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index eac6f78476..308d62c4b3 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -972,10 +972,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 1fcec689e6..d61c8b5e96 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'), |
