1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

gis: Fixed DecimalField verification in LayerMapping.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6708 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-11-20 15:13:55 +00:00
parent f23597cdd7
commit 85ce45bc44
6 changed files with 41 additions and 15 deletions

View File

@ -10,7 +10,7 @@ class City(models.Model):
class Interstate(models.Model):
name = models.CharField(max_length=20)
length = models.DecimalField(max_digits=7, decimal_places=2)
length = models.DecimalField(max_digits=6, decimal_places=2)
path = models.LineStringField()
objects = models.GeoManager()

View File

@ -88,14 +88,24 @@ class LayerMapTest(unittest.TestCase):
lm = LayerMapping(Interstate, inter_shp, inter_mapping, silent=True)
lm.save()
# Only one interstate should have imported correctly.
self.assertEqual(1, Interstate.objects.count())
# Two interstate should have imported correctly.
self.assertEqual(2, Interstate.objects.count())
# Verifying the values in the single feature w/the model.
# Verifying the values in the layer w/the model.
ds = DataSource(inter_shp)
feat = ds[0][0]
# Only the first two features of this shapefile are valid.
valid_feats = ds[0][:2]
for feat in valid_feats:
istate = Interstate.objects.get(name=feat['Name'].value)
if feat.fid == 0:
self.assertEqual(Decimal(str(feat['Length'])), istate.length)
elif feat.fid == 1:
# Everything but the first two decimal digits were truncated,
# because the Interstate model's `length` field has decimal_places=2.
self.assertAlmostEqual(feat.get('Length'), float(istate.length), 2)
for p1, p2 in zip(feat.geom, istate.path):
self.assertAlmostEqual(p1[0], p2[0], 6)
self.assertAlmostEqual(p1[1], p2[1], 6)

View File

@ -394,11 +394,27 @@ class LayerMapping(object):
d = Decimal(str(fld.value))
except:
raise InvalidDecimal('Could not construct decimal from: %s' % fld)
# Getting the decimal value as a tuple.
dtup = d.as_tuple()
if len(dtup[1]) > field_class.max_digits:
raise InvalidDecimal('More than the maximum # of digits encountered.')
elif len(dtup[1][dtup[2]:]) > field_class.decimal_places:
raise InvalidDecimal('More than the maximum # of decimal places encountered.')
digits = dtup[1]
d_idx = dtup[2] # index where the decimal is
# Maximum amount of precision, or digits to the left of the decimal.
max_prec = field_class.max_digits - field_class.decimal_places
# Getting the digits to the left of the decimal place for the
# given decimal.
if d_idx < 0:
n_prec = len(digits[:d_idx])
else:
n_prec = len(digits) + d_idx
# If we have more than the maximum digits allowed, then throw an
# InvalidDecimal exception.
if n_prec > max_prec:
raise InvalidDecimal('A DecimalField with max_digits %d, decimal_places %d must round to an absolute value less than 10^%d.' %
(field_class.max_digits, field_class.decimal_places, max_prec))
val = d
else:
val = fld.value
@ -467,7 +483,7 @@ class LayerMapping(object):
elif not self.silent:
print 'Ignoring Feature ID %s because: %s' % (feat.fid, msg)
else:
# Constructing the model using the constructed keyword args
# Constructing the model using the keyword args
if all_prepped:
m = self.model(**kwargs)
try: