From 8a281aa7fe76a9da2284f943964a9413697cff1f Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Wed, 7 Aug 2019 12:54:40 -0400 Subject: [PATCH] Fixed #30687 -- Fixed using of OuterRef() expressions in distance lookups. --- django/db/models/sql/query.py | 12 +++++++++--- tests/gis_tests/distapp/tests.py | 12 +++++++++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 1849d42081a..4ad1fb3f363 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -1054,15 +1054,21 @@ class Query(BaseExpression): elif isinstance(value, (list, tuple)): # The items of the iterable may be expressions and therefore need # to be resolved independently. + resolved_values = [] for sub_value in value: if hasattr(sub_value, 'resolve_expression'): if isinstance(sub_value, F): - sub_value.resolve_expression( + resolved_values.append(sub_value.resolve_expression( self, reuse=can_reuse, allow_joins=allow_joins, simple_col=simple_col, - ) + )) else: - sub_value.resolve_expression(self, reuse=can_reuse, allow_joins=allow_joins) + resolved_values.append(sub_value.resolve_expression( + self, reuse=can_reuse, allow_joins=allow_joins, + )) + else: + resolved_values.append(sub_value) + value = tuple(resolved_values) return value def solve_lookup_type(self, lookup): diff --git a/tests/gis_tests/distapp/tests.py b/tests/gis_tests/distapp/tests.py index 67558582dc9..d84e829868a 100644 --- a/tests/gis_tests/distapp/tests.py +++ b/tests/gis_tests/distapp/tests.py @@ -6,7 +6,7 @@ from django.contrib.gis.db.models.functions import ( from django.contrib.gis.geos import GEOSGeometry, LineString, Point from django.contrib.gis.measure import D # alias for Distance from django.db import NotSupportedError, connection -from django.db.models import F, Q +from django.db.models import Exists, F, OuterRef, Q from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature from ..utils import ( @@ -224,6 +224,16 @@ class DistanceTest(TestCase): with self.assertRaisesMessage(ValueError, msg): AustraliaCity.objects.filter(point__distance_lte=(Point(0, 0), D(m=100))).exists() + @skipUnlessDBFeature('supports_dwithin_lookup') + def test_dwithin_subquery(self): + """dwithin lookup in a subquery using OuterRef as a parameter.""" + qs = CensusZipcode.objects.annotate( + annotated_value=Exists(SouthTexasCity.objects.filter( + point__dwithin=(OuterRef('poly'), D(m=10)), + )) + ).filter(annotated_value=True) + self.assertEqual(self.get_names(qs), ['77002', '77025', '77401']) + ''' =============================