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 08654a99bb
.
Thanks Oli Warner for the detailed report.
This commit is contained in:
parent
fd9398816e
commit
277ed07209
|
@ -960,10 +960,13 @@ class Subquery(Expression):
|
||||||
def __init__(self, queryset, output_field=None, **extra):
|
def __init__(self, queryset, output_field=None, **extra):
|
||||||
self.queryset = queryset
|
self.queryset = queryset
|
||||||
self.extra = extra
|
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)
|
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):
|
def copy(self):
|
||||||
clone = super().copy()
|
clone = super().copy()
|
||||||
clone.queryset = clone.queryset.all()
|
clone.queryset = clone.queryset.all()
|
||||||
|
|
|
@ -9,4 +9,5 @@ Django 2.0.4 fixes several bugs in 2.0.3.
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed a crash when filtering with an ``Exists()`` annotation of a queryset
|
||||||
|
containing a single field (:ticket:`29195`).
|
||||||
|
|
|
@ -417,6 +417,10 @@ class BasicExpressionsTests(TestCase):
|
||||||
outer = Employee.objects.annotate(is_point_of_contact=Exists(inner))
|
outer = Employee.objects.annotate(is_point_of_contact=Exists(inner))
|
||||||
self.assertIs(outer.exists(), True)
|
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):
|
def test_subquery(self):
|
||||||
Company.objects.filter(name='Example Inc.').update(
|
Company.objects.filter(name='Example Inc.').update(
|
||||||
point_of_contact=Employee.objects.get(firstname='Joe', lastname='Smith'),
|
point_of_contact=Employee.objects.get(firstname='Joe', lastname='Smith'),
|
||||||
|
|
Loading…
Reference in New Issue