Fixed #25708 -- Fixed annotations with geometry values.

This commit is contained in:
Sergey Fedoseev 2015-11-09 11:33:40 +05:00 committed by Tim Graham
parent 4a246a02bd
commit f909fa84be
3 changed files with 39 additions and 0 deletions

View File

@ -312,6 +312,12 @@ class GeometryField(GeoSelectFormatMixin, BaseSpatialField):
"""
return connection.ops.get_distance(self, value, lookup_type)
def get_db_prep_value(self, value, connection, *args, **kwargs):
return connection.ops.Adapter(
super(GeometryField, self).get_db_prep_value(value, connection, *args, **kwargs),
**({'geography': True} if self.geography else {})
)
def from_db_value(self, value, expression, connection, context):
if value:
if not isinstance(value, Geometry):

View File

@ -579,6 +579,8 @@ class Value(Expression):
val = self.output_field.get_db_prep_save(val, connection=connection)
else:
val = self.output_field.get_db_prep_value(val, connection=connection)
if hasattr(self._output_field, 'get_placeholder'):
return self._output_field.get_placeholder(val, compiler, connection), [val]
if val is None:
# cx_Oracle does not always convert None to the appropriate
# NULL type (like in case expressions using numbers), so we

View File

@ -0,0 +1,31 @@
from unittest import skipUnless
from django.contrib.gis.db.models import GeometryField, Value, functions
from django.contrib.gis.geos import Point, Polygon
from django.test import TestCase, skipUnlessDBFeature
from ..utils import postgis
from .models import City
@skipUnlessDBFeature('gis_enabled')
class GeoExpressionsTests(TestCase):
fixtures = ['initial']
def test_geometry_value_annotation(self):
p = Point(1, 1, srid=4326)
point = City.objects.annotate(p=Value(p, GeometryField(srid=4326))).first().p
self.assertEqual(point, p)
@skipUnlessDBFeature('supports_transform')
def test_geometry_value_annotation_different_srid(self):
p = Point(1, 1, srid=32140)
point = City.objects.annotate(p=Value(p, GeometryField(srid=4326))).first().p
self.assertTrue(point.equals_exact(p.transform(4326, clone=True), 10 ** -5))
self.assertEqual(point.srid, 4326)
@skipUnless(postgis, 'Only postgis has geography fields.')
def test_geography_value(self):
p = Polygon(((1, 1), (1, 2), (2, 2), (2, 1), (1, 1)))
area = City.objects.annotate(a=functions.Area(Value(p, GeometryField(srid=4326, geography=True)))).first().a
self.assertAlmostEqual(area.sq_km, 12305.1, 0)