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
This commit is contained in:
Justin Bronn 2010-03-29 22:20:38 +00:00
parent 381b10c2c6
commit 7e5265785a
3 changed files with 20 additions and 3 deletions

View File

@ -51,7 +51,8 @@ class GeoQuery(sql.Query):
return obj return obj
def convert_values(self, value, field, connection): 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. extra selection objects into Geometry and Distance objects.
TODO: Make converted objects 'lazy' for less overhead. TODO: Make converted objects 'lazy' for less overhead.
""" """
@ -59,7 +60,11 @@ class GeoQuery(sql.Query):
# Running through Oracle's first. # Running through Oracle's first.
value = super(GeoQuery, self).convert_values(value, field or GeomField(), connection) 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 # Using the field's distance attribute, can instantiate
# `Distance` with the right context. # `Distance` with the right context.
value = Distance(**{field.distance_att : value}) value = Distance(**{field.distance_att : value})

View File

@ -26,11 +26,12 @@ class CensusZipcode(models.Model):
name = models.CharField(max_length=5) name = models.CharField(max_length=5)
poly = models.PolygonField(srid=4269) poly = models.PolygonField(srid=4269)
objects = models.GeoManager() objects = models.GeoManager()
def __unicode__(self): return self.name
class SouthTexasZipcode(models.Model): class SouthTexasZipcode(models.Model):
"Model for a few South Texas ZIP codes." "Model for a few South Texas ZIP codes."
name = models.CharField(max_length=5) name = models.CharField(max_length=5)
poly = models.PolygonField(srid=32140) poly = models.PolygonField(srid=32140, null=True)
objects = models.GeoManager() objects = models.GeoManager()
def __unicode__(self): return self.name def __unicode__(self): return self.name

View File

@ -362,6 +362,17 @@ class DistanceTest(unittest.TestCase):
for i, c in enumerate(SouthTexasCity.objects.perimeter(model_att='perim')): for i, c in enumerate(SouthTexasCity.objects.perimeter(model_att='perim')):
self.assertEqual(0, c.perim.m) 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(): def suite():
s = unittest.TestSuite() s = unittest.TestSuite()
s.addTest(unittest.makeSuite(DistanceTest)) s.addTest(unittest.makeSuite(DistanceTest))