Ticket #4004: FloatField.2.diff
File FloatField.2.diff, 5.9 KB (added by , 18 years ago) |
---|
-
fields.py
11 11 import time 12 12 13 13 __all__ = ( 14 'Field', 'CharField', 'IntegerField', 14 'Field', 'CharField', 'IntegerField', 'FloatField', 15 15 'DEFAULT_DATE_INPUT_FORMATS', 'DateField', 16 16 'DEFAULT_TIME_INPUT_FORMATS', 'TimeField', 17 17 'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField', … … 132 132 raise ValidationError(gettext(u'Ensure this value is greater than or equal to %s.') % self.min_value) 133 133 return value 134 134 135 class 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 135 179 DEFAULT_DATE_INPUT_FORMATS = ( 136 180 '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06' 137 181 '%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006' -
test_floatfield.py
1 import django.newforms as forms 2 from django.newforms.util import ValidationError 3 from copy import copy 4 import unittest 5 6 class 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 65 suite = unittest.TestLoader().loadTestsFromTestCase(TestFloatFieldValidation) 66 unittest.TextTestRunner(verbosity=2).run(suite) 67