Django

Code

Changeset 5680

Show
Ignore:
Timestamp:
07/13/07 04:09:59 (1 year ago)
Author:
mtredinnick
Message:

Fixed #4807 -- Fixed a couple of corner cases in decimal form input validation.
Based on a suggestion from Chriss Moffit.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/validators.py

    r5640 r5680  
    1515from django.utils.encoding import force_unicode 
    1616import re 
     17try: 
     18    from decimal import Decimal, DecimalException 
     19except ImportError: 
     20    from django.utils._decimal import Decimal, DecimalException    # Python 2.3 
    1721 
    1822_datere = r'\d{4}-\d{1,2}-\d{1,2}' 
     
    2731    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"' # quoted-string 
    2832    r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE)  # domain 
    29 decimal_re = re.compile(r'^-?(?P<digits>\d+)(\.(?P<decimals>\d+))?$') 
    3033integer_re = re.compile(r'^-?\d+$') 
    3134ip4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$') 
     
    416419 
    417420    def __call__(self, field_data, all_data): 
    418         match = decimal_re.search(str(field_data)) 
    419         if not match: 
     421        try: 
     422            val = Decimal(field_data) 
     423        except DecimalException: 
    420424            raise ValidationError, _("Please enter a valid decimal number.") 
    421          
    422         digits = len(match.group('digits') or '') 
    423         decimals = len(match.group('decimals') or '') 
    424          
     425 
     426        pieces = str(val).split('.') 
     427        decimals = (len(pieces) == 2) and len(pieces[1]) or 0 
     428        digits = len(pieces[0]) 
     429 
    425430        if digits + decimals > self.max_digits: 
    426431            raise ValidationError, ungettext("Please enter a valid decimal number with at most %s total digit.", 
  • django/trunk/django/newforms/fields.py

    r5669 r5680  
    1212from util import ErrorList, ValidationError 
    1313from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple 
     14 
     15try: 
     16    from decimal import Decimal, DecimalException 
     17except ImportError: 
     18    from django.utils._decimal import Decimal, DecimalException 
    1419 
    1520__all__ = ( 
     
    163168        return value 
    164169 
    165 decimal_re = re.compile(r'^-?(?P<digits>\d+)(\.(?P<decimals>\d+))?$') 
    166  
    167170class DecimalField(Field): 
    168171    def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): 
     
    182185            return None 
    183186        value = value.strip() 
    184         match = decimal_re.search(value) 
    185         if not match: 
     187        try: 
     188            value = Decimal(value) 
     189        except DecimalException: 
    186190            raise ValidationError(ugettext('Enter a number.')) 
    187         else: 
    188             value = Decimal(value) 
    189         digits = len(match.group('digits') or '') 
    190         decimals = len(match.group('decimals') or '') 
     191        pieces = str(value).split('.') 
     192        decimals = (len(pieces) == 2) and len(pieces[1]) or 0 
     193        digits = len(pieces[0]) 
    191194        if self.max_value is not None and value > self.max_value: 
    192195            raise ValidationError(ugettext('Ensure this value is less than or equal to %s.') % self.max_value) 
  • django/trunk/tests/regressiontests/forms/tests.py

    r5609 r5680  
    11771177>>> f.clean('0.5') 
    11781178Decimal("0.5") 
     1179>>> f.clean('.5') 
     1180Decimal("0.5") 
     1181>>> f.clean('00.50') 
     1182Decimal("0.50") 
    11791183 
    11801184# DateField ###################################################################