From 7e5265785a7be403d84b3d8b2d23e295aa1f7d56 Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Mon, 29 Mar 2010 22:20:38 +0000 Subject: [PATCH] Fixed #10594 -- `GeoQuerySet` measurment methods no longer crash on geometry fields with NULL values. Thanks, whiteinge for the bug report and yourcelf for the initial patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12885 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/gis/db/models/sql/query.py | 9 +++++++-- django/contrib/gis/tests/distapp/models.py | 3 ++- django/contrib/gis/tests/distapp/tests.py | 11 +++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/django/contrib/gis/db/models/sql/query.py b/django/contrib/gis/db/models/sql/query.py index eeda456595..c300dcd527 100644 --- a/django/contrib/gis/db/models/sql/query.py +++ b/django/contrib/gis/db/models/sql/query.py @@ -51,7 +51,8 @@ class GeoQuery(sql.Query): return obj def convert_values(self, value, field, connection): - """ Using the same routines that Oracle does we can convert our + """ + Using the same routines that Oracle does we can convert our extra selection objects into Geometry and Distance objects. TODO: Make converted objects 'lazy' for less overhead. """ @@ -59,7 +60,11 @@ class GeoQuery(sql.Query): # Running through Oracle's first. value = super(GeoQuery, self).convert_values(value, field or GeomField(), connection) - if isinstance(field, DistanceField): + if value is None: + # Output from spatial function is NULL (e.g., called + # function on a geometry field with NULL value). + pass + elif isinstance(field, DistanceField): # Using the field's distance attribute, can instantiate # `Distance` with the right context. value = Distance(**{field.distance_att : value}) diff --git a/django/contrib/gis/tests/distapp/models.py b/django/contrib/gis/tests/distapp/models.py index 4030761578..76e7d3a03f 100644 --- a/django/contrib/gis/tests/distapp/models.py +++ b/django/contrib/gis/tests/distapp/models.py @@ -26,11 +26,12 @@ class CensusZipcode(models.Model): name = models.CharField(max_length=5) poly = models.PolygonField(srid=4269) objects = models.GeoManager() + def __unicode__(self): return self.name class SouthTexasZipcode(models.Model): "Model for a few South Texas ZIP codes." name = models.CharField(max_length=5) - poly = models.PolygonField(srid=32140) + poly = models.PolygonField(srid=32140, null=True) objects = models.GeoManager() def __unicode__(self): return self.name diff --git a/django/contrib/gis/tests/distapp/tests.py b/django/contrib/gis/tests/distapp/tests.py index e7def05955..28e50a3571 100644 --- a/django/contrib/gis/tests/distapp/tests.py +++ b/django/contrib/gis/tests/distapp/tests.py @@ -362,6 +362,17 @@ class DistanceTest(unittest.TestCase): for i, c in enumerate(SouthTexasCity.objects.perimeter(model_att='perim')): self.assertEqual(0, c.perim.m) + def test09_measurement_null_fields(self): + "Testing the measurement GeoQuerySet methods on fields with NULL values." + # Creating SouthTexasZipcode w/NULL value. + SouthTexasZipcode.objects.create(name='78212') + # Performing distance/area queries against the NULL PolygonField, + # and ensuring the result of the operations is None. + htown = SouthTexasCity.objects.get(name='Downtown Houston') + z = SouthTexasZipcode.objects.distance(htown.point).area().get(name='78212') + self.assertEqual(None, z.distance) + self.assertEqual(None, z.area) + def suite(): s = unittest.TestSuite() s.addTest(unittest.makeSuite(DistanceTest))