Commit 72713310 authored by Gary Wilson Jr's avatar Gary Wilson Jr
Browse files

Fixed #8290 -- Fixed DecimalField's cleaning of values with a large number of...

Fixed #8290 -- Fixed DecimalField's cleaning of values with a large number of decimal places, based on patch from dgouldin.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8391 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 9d1ec0b5
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -244,18 +244,28 @@ class DecimalField(Field):
            value = Decimal(value)
        except DecimalException:
            raise ValidationError(self.error_messages['invalid'])
        pieces = str(value).lstrip("-").split('.')
        decimals = (len(pieces) == 2) and len(pieces[1]) or 0
        digits = len(pieces[0])

        sign, digittuple, exponent = value.as_tuple()
        decimals = abs(exponent)
        # digittuple doesn't include any leading zeros.
        digits = len(digittuple)
        if decimals >= digits:
            # We have leading zeros up to or past the decimal point.  Count
            # everything past the decimal point as a digit.  We also add one
            # for leading zeros before the decimal point (any number of leading
            # whole zeros collapse to one digit).
            digits = decimals + 1
        whole_digits = digits - decimals

        if self.max_value is not None and value > self.max_value:
            raise ValidationError(self.error_messages['max_value'] % self.max_value)
        if self.min_value is not None and value < self.min_value:
            raise ValidationError(self.error_messages['min_value'] % self.min_value)
        if self.max_digits is not None and (digits + decimals) > self.max_digits:
        if self.max_digits is not None and digits > self.max_digits:
            raise ValidationError(self.error_messages['max_digits'] % self.max_digits)
        if self.decimal_places is not None and decimals > self.decimal_places:
            raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places)
        if self.max_digits is not None and self.decimal_places is not None and digits > (self.max_digits - self.decimal_places):
        if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places):
            raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places))
        return value

+27 −0
Original line number Diff line number Diff line
@@ -403,6 +403,33 @@ True
>>> f.clean('00.50') == Decimal("0.50")
True


>>> f = DecimalField(decimal_places=2)
>>> f.clean('0.00000001')
Traceback (most recent call last):
...
ValidationError: [u'Ensure that there are no more than 2 decimal places.']


>>> f = DecimalField(max_digits=3)

# Leading whole zeros "collapse" to one digit.
>>> f.clean('0000000.10') == Decimal("0.1")
True
>>> f.clean('0000000.100')
Traceback (most recent call last):
...
ValidationError: [u'Ensure that there are no more than 3 digits in total.']

# Only leading whole zeros "collapse" to one digit.
>>> f.clean('000000.02') == Decimal('0.02')
True
>>> f.clean('000000.002')
Traceback (most recent call last):
...
ValidationError: [u'Ensure that there are no more than 3 digits in total.']


# DateField ###################################################################

>>> import datetime