Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #8290 -- Fixed DecimalField's cleaning of values with a large n…

…umber of decimal places, based on patch from dgouldin.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8391 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 727133109cfb37d73da38d760198eb300125ddb0 1 parent 9d1ec0b
Gary Wilson Jr. authored August 15, 2008
20  django/forms/fields.py
@@ -244,18 +244,28 @@ def clean(self, value):
244 244
             value = Decimal(value)
245 245
         except DecimalException:
246 246
             raise ValidationError(self.error_messages['invalid'])
247  
-        pieces = str(value).lstrip("-").split('.')
248  
-        decimals = (len(pieces) == 2) and len(pieces[1]) or 0
249  
-        digits = len(pieces[0])
  247
+
  248
+        sign, digittuple, exponent = value.as_tuple()
  249
+        decimals = abs(exponent)
  250
+        # digittuple doesn't include any leading zeros.
  251
+        digits = len(digittuple)
  252
+        if decimals >= digits:
  253
+            # We have leading zeros up to or past the decimal point.  Count
  254
+            # everything past the decimal point as a digit.  We also add one
  255
+            # for leading zeros before the decimal point (any number of leading
  256
+            # whole zeros collapse to one digit).
  257
+            digits = decimals + 1
  258
+        whole_digits = digits - decimals
  259
+
250 260
         if self.max_value is not None and value > self.max_value:
251 261
             raise ValidationError(self.error_messages['max_value'] % self.max_value)
252 262
         if self.min_value is not None and value < self.min_value:
253 263
             raise ValidationError(self.error_messages['min_value'] % self.min_value)
254  
-        if self.max_digits is not None and (digits + decimals) > self.max_digits:
  264
+        if self.max_digits is not None and digits > self.max_digits:
255 265
             raise ValidationError(self.error_messages['max_digits'] % self.max_digits)
256 266
         if self.decimal_places is not None and decimals > self.decimal_places:
257 267
             raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places)
258  
-        if self.max_digits is not None and self.decimal_places is not None and digits > (self.max_digits - self.decimal_places):
  268
+        if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places):
259 269
             raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places))
260 270
         return value
261 271
 
27  tests/regressiontests/forms/fields.py
@@ -403,6 +403,33 @@
403 403
 >>> f.clean('00.50') == Decimal("0.50")
404 404
 True
405 405
 
  406
+
  407
+>>> f = DecimalField(decimal_places=2)
  408
+>>> f.clean('0.00000001')
  409
+Traceback (most recent call last):
  410
+...
  411
+ValidationError: [u'Ensure that there are no more than 2 decimal places.']
  412
+
  413
+
  414
+>>> f = DecimalField(max_digits=3)
  415
+
  416
+# Leading whole zeros "collapse" to one digit.
  417
+>>> f.clean('0000000.10') == Decimal("0.1")
  418
+True
  419
+>>> f.clean('0000000.100')
  420
+Traceback (most recent call last):
  421
+...
  422
+ValidationError: [u'Ensure that there are no more than 3 digits in total.']
  423
+
  424
+# Only leading whole zeros "collapse" to one digit.
  425
+>>> f.clean('000000.02') == Decimal('0.02')
  426
+True
  427
+>>> f.clean('000000.002')
  428
+Traceback (most recent call last):
  429
+...
  430
+ValidationError: [u'Ensure that there are no more than 3 digits in total.']
  431
+
  432
+
406 433
 # DateField ###################################################################
407 434
 
408 435
 >>> import datetime

0 notes on commit 7271331

Please sign in to comment.
Something went wrong with that request. Please try again.