[3.0.x] Fixed #31607 -- Fixed evaluated Subquery equality.
Regression in691def10a0
. Backport ofa125da6a7c
from master
This commit is contained in:
parent
92acf1022f
commit
0ba5aadb33
|
@ -1040,11 +1040,18 @@ class Subquery(Expression):
|
||||||
def __init__(self, queryset, output_field=None, **extra):
|
def __init__(self, queryset, output_field=None, **extra):
|
||||||
self.query = queryset.query
|
self.query = queryset.query
|
||||||
self.extra = extra
|
self.extra = extra
|
||||||
|
# Prevent the QuerySet from being evaluated.
|
||||||
|
self.queryset = queryset._chain(_result_cache=[], prefetch_done=True)
|
||||||
super().__init__(output_field)
|
super().__init__(output_field)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
state = super().__getstate__()
|
state = super().__getstate__()
|
||||||
state.pop('_constructor_args', None)
|
args, kwargs = state['_constructor_args']
|
||||||
|
if args:
|
||||||
|
args = (self.queryset, *args[1:])
|
||||||
|
else:
|
||||||
|
kwargs['queryset'] = self.queryset
|
||||||
|
state['_constructor_args'] = args, kwargs
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def get_source_expressions(self):
|
def get_source_expressions(self):
|
||||||
|
|
|
@ -512,6 +512,25 @@ class BasicExpressionsTests(TestCase):
|
||||||
Employee.objects.exclude(company_point_of_contact_set=None).values('pk')
|
Employee.objects.exclude(company_point_of_contact_set=None).values('pk')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_subquery_eq(self):
|
||||||
|
qs = Employee.objects.annotate(
|
||||||
|
is_ceo=Exists(Company.objects.filter(ceo=OuterRef('pk'))),
|
||||||
|
is_point_of_contact=Exists(
|
||||||
|
Company.objects.filter(point_of_contact=OuterRef('pk')),
|
||||||
|
),
|
||||||
|
small_company=Exists(
|
||||||
|
queryset=Company.objects.filter(num_employees__lt=200),
|
||||||
|
),
|
||||||
|
).filter(is_ceo=True, is_point_of_contact=False, small_company=True)
|
||||||
|
self.assertNotEqual(
|
||||||
|
qs.query.annotations['is_ceo'],
|
||||||
|
qs.query.annotations['is_point_of_contact'],
|
||||||
|
)
|
||||||
|
self.assertNotEqual(
|
||||||
|
qs.query.annotations['is_ceo'],
|
||||||
|
qs.query.annotations['small_company'],
|
||||||
|
)
|
||||||
|
|
||||||
def test_in_subquery(self):
|
def test_in_subquery(self):
|
||||||
# This is a contrived test (and you really wouldn't write this query),
|
# This is a contrived test (and you really wouldn't write this query),
|
||||||
# but it is a succinct way to test the __in=Subquery() construct.
|
# but it is a succinct way to test the __in=Subquery() construct.
|
||||||
|
|
Loading…
Reference in New Issue