From 85ce45bc441e4ace2fba83bc2d2432e22ec9da94 Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Tue, 20 Nov 2007 15:13:55 +0000 Subject: [PATCH] gis: Fixed DecimalField verification in LayerMapping. git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6708 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- .../layermap/interstates/interstates.dbf | Bin 307 -> 412 bytes .../layermap/interstates/interstates.shp | Bin 788 -> 892 bytes .../layermap/interstates/interstates.shx | Bin 116 -> 124 bytes django/contrib/gis/tests/layermap/models.py | 2 +- django/contrib/gis/tests/layermap/tests.py | 28 ++++++++++++------ django/contrib/gis/utils/layermapping.py | 26 ++++++++++++---- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/django/contrib/gis/tests/layermap/interstates/interstates.dbf b/django/contrib/gis/tests/layermap/interstates/interstates.dbf index 7b551461dac65e5f687e0913c2322499335cfe0e..a88d171588b617087772dc03944a41d95c38f7a7 100644 GIT binary patch delta 82 zcmdnYG>4g$Ii6jLc_QmE*098!%#?|R?h_k0WDJdrP4rC7%q=VppupHf!85N6u7p(- Lq{LJYCJm(lj-?d& delta 43 wcmbQkyqSrWIi6jLX(H<}4$r)@#GK3&!-*ID1x@tK4UCPAjEs$q4J<(b00r0!b^rhX diff --git a/django/contrib/gis/tests/layermap/interstates/interstates.shp b/django/contrib/gis/tests/layermap/interstates/interstates.shp index 57de1e7dc5f0cbb6cbf8b0826dbb4f65e62eff31..6d93de75ec2c0ebe91e1f0a21f2413d9dfa9f813 100644 GIT binary patch delta 21 dcmbQj_J?hPG~>RFGC!DD7#J9sCvRX%0RT^g27Ukl delta 12 TcmeyvHid11G-KCBnIB959~%Uk diff --git a/django/contrib/gis/tests/layermap/interstates/interstates.shx b/django/contrib/gis/tests/layermap/interstates/interstates.shx index a277b9844983a64460f1560161cb688ceb2c6f1e..7b9088ac5b9c0f5d418c75f88a493f17be95a2ee 100644 GIT binary patch delta 18 ZcmXS^nIO$*H&G^ngMopui-Cc`001oC1ET-{ delta 9 Qcmb;^nIO$*HBlx401w9k+yDRo diff --git a/django/contrib/gis/tests/layermap/models.py b/django/contrib/gis/tests/layermap/models.py index 512cdb42af..6b575f5c46 100644 --- a/django/contrib/gis/tests/layermap/models.py +++ b/django/contrib/gis/tests/layermap/models.py @@ -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() diff --git a/django/contrib/gis/tests/layermap/tests.py b/django/contrib/gis/tests/layermap/tests.py index c7e67a63c0..825e3d7e69 100644 --- a/django/contrib/gis/tests/layermap/tests.py +++ b/django/contrib/gis/tests/layermap/tests.py @@ -88,17 +88,27 @@ 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] - istate = Interstate.objects.get(name=feat['Name'].value) - self.assertEqual(Decimal(str(feat['Length'])), istate.length) - for p1, p2 in zip(feat.geom, istate.path): - self.assertAlmostEqual(p1[0], p2[0], 6) - self.assertAlmostEqual(p1[1], p2[1], 6) + + # 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) def suite(): s = unittest.TestSuite() diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index 9534d86082..65b855bbc2 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -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: