Fixed #30687 -- Fixed using of OuterRef() expressions in distance lookups.

This commit is contained in:
Andrew Brown 2019-08-07 12:54:40 -04:00 committed by Mariusz Felisiak
parent 8289fc55ff
commit 8a281aa7fe
2 changed files with 20 additions and 4 deletions

View File

@ -1054,15 +1054,21 @@ class Query(BaseExpression):
elif isinstance(value, (list, tuple)): elif isinstance(value, (list, tuple)):
# The items of the iterable may be expressions and therefore need # The items of the iterable may be expressions and therefore need
# to be resolved independently. # to be resolved independently.
resolved_values = []
for sub_value in value: for sub_value in value:
if hasattr(sub_value, 'resolve_expression'): if hasattr(sub_value, 'resolve_expression'):
if isinstance(sub_value, F): if isinstance(sub_value, F):
sub_value.resolve_expression( resolved_values.append(sub_value.resolve_expression(
self, reuse=can_reuse, allow_joins=allow_joins, self, reuse=can_reuse, allow_joins=allow_joins,
simple_col=simple_col, simple_col=simple_col,
) ))
else: 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 return value
def solve_lookup_type(self, lookup): def solve_lookup_type(self, lookup):

View File

@ -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.geos import GEOSGeometry, LineString, Point
from django.contrib.gis.measure import D # alias for Distance from django.contrib.gis.measure import D # alias for Distance
from django.db import NotSupportedError, connection 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 django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
from ..utils import ( from ..utils import (
@ -224,6 +224,16 @@ class DistanceTest(TestCase):
with self.assertRaisesMessage(ValueError, msg): with self.assertRaisesMessage(ValueError, msg):
AustraliaCity.objects.filter(point__distance_lte=(Point(0, 0), D(m=100))).exists() 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'])
''' '''
============================= =============================