Django

Code

Ticket #4004: FloatField.2.diff

File FloatField.2.diff, 5.9 kB (added by tonnzor <tonn81@gmail.com>, 2 years ago)

FloatField? (fixed error message)

  • fields.py

    old new  
    1111import time 
    1212 
    1313__all__ = ( 
    14     'Field', 'CharField', 'IntegerField', 
     14    'Field', 'CharField', 'IntegerField', 'FloatField', 
    1515    'DEFAULT_DATE_INPUT_FORMATS', 'DateField', 
    1616    'DEFAULT_TIME_INPUT_FORMATS', 'TimeField', 
    1717    'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField', 
     
    132132            raise ValidationError(gettext(u'Ensure this value is greater than or equal to %s.') % self.min_value) 
    133133        return value 
    134134 
     135class FloatField(Field): 
     136    def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): 
     137        self.max_value, self.min_value, self.max_digits, self.decimal_places = max_value, min_value, max_digits, decimal_places 
     138        super(FloatField, self).__init__(*args, **kwargs) 
     139 
     140    def clean(self, value): 
     141        """ 
     142        Validates that float() can be called on the input. Returns the result 
     143        of float(). Returns None for empty values. 
     144        """ 
     145        super(FloatField, self).clean(value) 
     146        if value in EMPTY_VALUES: 
     147            return None 
     148        value = str(value).replace(',', '.')  # "," is used as fractional part separator in some languages (Russian, etc.) 
     149        value = value.strip()  # remove useless spaces 
     150        value = re.sub('^-\s+', '-', value) 
     151        value = re.sub('\s*\.\s*', '.', value) 
     152        try: 
     153            value = float(value) 
     154        except (ValueError, TypeError): 
     155            raise ValidationError(gettext(u'Enter a number.')) 
     156        if self.max_value is not None and value > self.max_value: 
     157            raise ValidationError(gettext(u'Ensure this value is less than or equal to %s.') % self.max_value) 
     158        if self.min_value is not None and value < self.min_value: 
     159            raise ValidationError(gettext(u'Ensure this value is greater than or equal to %s.') % self.min_value) 
     160        if self.decimal_places is not None: 
     161            regex = (r'\.\d{1,%d}$' % self.decimal_places) if self.decimal_places > 0 else r'\.0$' 
     162            regex = re.compile(regex) 
     163            if not regex.search(str(value)): 
     164                raise ValidationError(gettext(u"Ensure this value's fractional part has at most %d digits") % self.decimal_places) 
     165        if self.max_digits is not None and self.decimal_places is not None: 
     166            regex = r'^[-]?\d{1,%d}\.' % (self.max_digits - self.decimal_places) 
     167            regex = re.compile(regex) 
     168            if not regex.search(str(value)): 
     169                raise ValidationError(gettext(u"Ensure this value's sharp part has at most %d digits") % (self.max_digits - self.decimal_places)) 
     170        elif self.max_digits is not None: 
     171            regex = r'^[-]?\d{1,%d}$' % self.max_digits 
     172            regex = re.compile(regex) 
     173            value_sams_trailing_zero = re.sub('\.(0$)?', '', str(value)) 
     174            if not regex.search(value_sams_trailing_zero): 
     175                raise ValidationError(gettext(u'Ensure this value has at most %d digits (including sharp part)') % self.max_digits) 
     176        return value 
     177 
     178 
    135179DEFAULT_DATE_INPUT_FORMATS = ( 
    136180    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06' 
    137181    '%b %d %Y', '%b %d, %Y',            # 'Oct 25 2006', 'Oct 25, 2006' 
  • test_floatfield.py

    old new  
     1import django.newforms as forms 
     2from django.newforms.util import ValidationError 
     3from copy import copy 
     4import unittest 
     5 
     6class TestFloatFieldValidation(unittest.TestCase): 
     7     
     8    def mutate_data(self, data): 
     9        for row in copy(data): 
     10            if row[0].startswith('0.'): 
     11                data.append((row[0][1:], row[1], row[2])) 
     12        for row in copy(data): 
     13            if not row[0].startswith('-'): 
     14                data.append(('-' + row[0], row[1], row[2])) 
     15        for row in copy(data): 
     16            if 0 > row[0].find('.'): 
     17                data.append((row[0] + '.0', row[1], row[2])) 
     18 
     19    def mutate_data_dots(self, data): 
     20        for row in copy(data): 
     21            if 0 <= row[0].find('.'): 
     22                data.append((row[0].replace('.', ','), row[1], row[2])) 
     23 
     24    def setUp(self): 
     25        self.valid_data = [ 
     26            ('000',   None, None), 
     27            ('100',   None, None), 
     28            (' 100 ',   None, None), 
     29            ('0.364', None, None), 
     30         
     31            ('100',   3, None), 
     32            ('0.364', 4, None), 
     33         
     34            ('100',   None, 0), 
     35            ('0.364', None, 3), 
     36         
     37            ('100',   3, 0), 
     38            ('0.364', 4, 3), 
     39            ] 
     40 
     41        self.invalid_data = [ 
     42            ('sda',     None, None), 
     43            ('1,000.0', None, None), 
     44            ('--10',    None, None), 
     45            ('10-20',   None, None), 
     46            ] 
     47 
     48        self.mutate_data(self.valid_data) 
     49        self.mutate_data_dots(self.valid_data) 
     50        self.mutate_data(self.invalid_data) 
     51 
     52    def test_valid_values_passes(self): 
     53        for text, max_digits, decimal_places in self.valid_data: 
     54            field = forms.FloatField(max_digits = max_digits, decimal_places = decimal_places) 
     55            try: 
     56                field.clean(text) 
     57            except ValidationError, e: 
     58                self.fail('%s : %s' % (text, e)) 
     59 
     60    def test_invalid_values_excepts(self): 
     61        for text, max_digits, decimal_places in self.invalid_data: 
     62            field = forms.FloatField(max_digits = max_digits, decimal_places = decimal_places) 
     63            self.assertRaises(ValidationError, field.clean, text) 
     64 
     65suite = unittest.TestLoader().loadTestsFromTestCase(TestFloatFieldValidation) 
     66unittest.TextTestRunner(verbosity=2).run(suite) 
     67