summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShai Berger <shai@platonix.com>2016-01-26 00:50:46 +0200
committerTim Graham <timograham@gmail.com>2016-02-09 10:04:54 -0500
commitbb51dc902dc760b6fd03b860335fd99f47e2e13d (patch)
tree88a42d1a13d52e5cb725f959163484f8be343f90
parent75143fa13f4f1ad2be84a103f7ce0eef9d06d3b4 (diff)
Refs #26112 -- Fixed aggregate GIS test on Oracle.
Made sure the test doesn't try to aggregate over MultiPolygonField and made AreaField turn decimals into floats on the way from the DB. Thanks Daniel Wiesmann, Jani Tiainen, and Tim Graham for review and discussion.
-rw-r--r--django/contrib/gis/db/models/sql/conversion.py6
-rw-r--r--docs/releases/1.10.txt9
-rw-r--r--tests/gis_tests/geoapp/test_functions.py4
3 files changed, 17 insertions, 2 deletions
diff --git a/django/contrib/gis/db/models/sql/conversion.py b/django/contrib/gis/db/models/sql/conversion.py
index afc1053790..acc277ed62 100644
--- a/django/contrib/gis/db/models/sql/conversion.py
+++ b/django/contrib/gis/db/models/sql/conversion.py
@@ -4,6 +4,8 @@ database.
"""
from __future__ import unicode_literals
+from decimal import Decimal
+
from django.contrib.gis.db.models.fields import GeoSelectFormatMixin
from django.contrib.gis.geometry.backend import Geometry
from django.contrib.gis.measure import Area, Distance
@@ -27,6 +29,10 @@ class AreaField(BaseField):
def from_db_value(self, value, expression, connection, context):
if connection.features.interprets_empty_strings_as_nulls and value == '':
value = None
+ # If the database returns a Decimal, convert it to a float as expected
+ # by the Python geometric objects.
+ if isinstance(value, Decimal):
+ value = float(value)
# If the units are known, convert value into area measure.
if value is not None and self.area_att:
value = Area(**{self.area_att: value})
diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt
index 0e7381a972..fd2b1a5d40 100644
--- a/docs/releases/1.10.txt
+++ b/docs/releases/1.10.txt
@@ -353,7 +353,10 @@ Backwards incompatible changes in 1.10
Database backend API
--------------------
-* ...
+* GIS's ``AreaField`` uses an unspecified underlying numeric type that could in
+ practice be any numeric Python type. ``decimal.Decimal`` values retrieved
+ from the database are now converted to ``float`` to make it easier to combine
+ them with values used by the GIS libraries.
``select_related()`` prohibits non-relational fields for nested relations
-------------------------------------------------------------------------
@@ -515,6 +518,10 @@ Miscellaneous
argument of the ``render_options()`` method is also removed, making
``selected_choices`` the first argument.
+* On Oracle/GIS, the :class:`~django.contrib.gis.db.models.functions.Area`
+ aggregate function now returns a ``float`` instead of ``decimal.Decimal``.
+ (It's still wrapped in a measure of square meters.)
+
.. _deprecated-features-1.10:
Features deprecated in 1.10
diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py
index aeb1007c56..344fa03e61 100644
--- a/tests/gis_tests/geoapp/test_functions.py
+++ b/tests/gis_tests/geoapp/test_functions.py
@@ -240,7 +240,9 @@ class GISFunctionsTests(TestCase):
CountryWebMercator.objects.create(name=c.name, mpoly=c.mpoly)
# Test in projected coordinate system
qs = CountryWebMercator.objects.annotate(area_sum=Sum(functions.Area('mpoly')))
- for c in qs:
+ # Some backends (e.g. Oracle) cannot group by multipolygon values, so
+ # defer such fields in the aggregation query.
+ for c in qs.defer('mpoly'):
result = c.area_sum
# If the result is a measure object, get value.
if isinstance(result, Area):