Django

Code

Changeset 8391

Show
Ignore:
Timestamp:
08/15/08 15:09:47 (4 months ago)
Author:
gwilson
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/forms/fields.py

    r8291 r8391  
    245245        except DecimalException: 
    246246            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 
    250260        if self.max_value is not None and value > self.max_value: 
    251261            raise ValidationError(self.error_messages['max_value'] % self.max_value) 
    252262        if self.min_value is not None and value < self.min_value: 
    253263            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: 
    255265            raise ValidationError(self.error_messages['max_digits'] % self.max_digits) 
    256266        if self.decimal_places is not None and decimals > self.decimal_places: 
    257267            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): 
    259269            raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) 
    260270        return value 
  • django/trunk/tests/regressiontests/forms/fields.py

    r8190 r8391  
    403403>>> f.clean('00.50') == Decimal("0.50") 
    404404True 
     405 
     406 
     407>>> f = DecimalField(decimal_places=2) 
     408>>> f.clean('0.00000001') 
     409Traceback (most recent call last): 
     410... 
     411ValidationError: [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") 
     418True 
     419>>> f.clean('0000000.100') 
     420Traceback (most recent call last): 
     421... 
     422ValidationError: [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') 
     426True 
     427>>> f.clean('000000.002') 
     428Traceback (most recent call last): 
     429... 
     430ValidationError: [u'Ensure that there are no more than 3 digits in total.'] 
     431 
    405432 
    406433# DateField ###################################################################