Changeset 6693
- Timestamp:
- 11/18/07 06:07:25 (1 year ago)
- Files:
-
- django/branches/queryset-refactor/django/newforms/fields.py (modified) (25 diffs)
- django/branches/queryset-refactor/django/newforms/util.py (modified) (2 diffs)
- django/branches/queryset-refactor/django/test/testcases.py (modified) (1 diff)
- django/branches/queryset-refactor/docs/newforms.txt (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/queryset-refactor/django/newforms/fields.py
r6690 r6693 50 50 creation_counter = 0 51 51 52 def __init__(self, required=True, widget=None, label=None, initial=None, help_text=None): 52 def __init__(self, required=True, widget=None, label=None, initial=None, 53 help_text=None, error_messages=None): 53 54 # required -- Boolean that specifies whether the field is required. 54 55 # True by default. … … 107 108 """ 108 109 if self.required and value in EMPTY_VALUES: 109 raise ValidationError( ugettext(u'This field is required.'))110 raise ValidationError(self.error_messages['required']) 110 111 return value 111 112 … … 142 143 value_length = len(value) 143 144 if self.max_length is not None and value_length > self.max_length: 144 raise ValidationError( ugettext(u'Ensure this value has at most %(max)d characters (it has %(length)d).')% {'max': self.max_length, 'length': value_length})145 raise ValidationError(self.error_messages['max_length'] % {'max': self.max_length, 'length': value_length}) 145 146 if self.min_length is not None and value_length < self.min_length: 146 raise ValidationError( ugettext(u'Ensure this value has at least %(min)d characters (it has %(length)d).')% {'min': self.min_length, 'length': value_length})147 raise ValidationError(self.error_messages['min_length'] % {'min': self.min_length, 'length': value_length}) 147 148 return value 148 149 … … 174 175 value = int(str(value)) 175 176 except (ValueError, TypeError): 176 raise ValidationError( ugettext(u'Enter a whole number.'))177 raise ValidationError(self.error_messages['invalid']) 177 178 if self.max_value is not None and value > self.max_value: 178 raise ValidationError( ugettext(u'Ensure this value is less than or equal to %s.')% self.max_value)179 raise ValidationError(self.error_messages['max_value'] % self.max_value) 179 180 if self.min_value is not None and value < self.min_value: 180 raise ValidationError( ugettext(u'Ensure this value is greater than or equal to %s.')% self.min_value)181 raise ValidationError(self.error_messages['min_value'] % self.min_value) 181 182 return value 182 183 … … 203 204 value = float(value) 204 205 except (ValueError, TypeError): 205 raise ValidationError( ugettext('Enter a number.'))206 raise ValidationError(self.error_messages['invalid']) 206 207 if self.max_value is not None and value > self.max_value: 207 raise ValidationError( ugettext('Ensure this value is less than or equal to %s.')% self.max_value)208 raise ValidationError(self.error_messages['max_value'] % self.max_value) 208 209 if self.min_value is not None and value < self.min_value: 209 raise ValidationError( ugettext('Ensure this value is greater than or equal to %s.')% self.min_value)210 raise ValidationError(self.error_messages['min_value'] % self.min_value) 210 211 return value 211 212 … … 239 240 value = Decimal(value) 240 241 except DecimalException: 241 raise ValidationError( ugettext('Enter a number.'))242 raise ValidationError(self.error_messages['invalid']) 242 243 pieces = str(value).lstrip("-").split('.') 243 244 decimals = (len(pieces) == 2) and len(pieces[1]) or 0 244 245 digits = len(pieces[0]) 245 246 if self.max_value is not None and value > self.max_value: 246 raise ValidationError( ugettext('Ensure this value is less than or equal to %s.')% self.max_value)247 raise ValidationError(self.error_messages['max_value'] % self.max_value) 247 248 if self.min_value is not None and value < self.min_value: 248 raise ValidationError( ugettext('Ensure this value is greater than or equal to %s.')% self.min_value)249 raise ValidationError(self.error_messages['min_value'] % self.min_value) 249 250 if self.max_digits is not None and (digits + decimals) > self.max_digits: 250 raise ValidationError( ugettext('Ensure that there are no more than %s digits in total.')% self.max_digits)251 raise ValidationError(self.error_messages['max_digits'] % self.max_digits) 251 252 if self.decimal_places is not None and decimals > self.decimal_places: 252 raise ValidationError( ugettext('Ensure that there are no more than %s decimal places.')% self.decimal_places)253 raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places) 253 254 if self.max_digits is not None and self.decimal_places is not None and digits > (self.max_digits - self.decimal_places): 254 raise ValidationError( ugettext('Ensure that there are no more than %s digits before the decimal point.')% (self.max_digits - self.decimal_places))255 raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) 255 256 return value 256 257 … … 289 290 except ValueError: 290 291 continue 291 raise ValidationError( ugettext(u'Enter a valid date.'))292 raise ValidationError(self.error_messages['invalid']) 292 293 293 294 DEFAULT_TIME_INPUT_FORMATS = ( … … 320 321 except ValueError: 321 322 continue 322 raise ValidationError( ugettext(u'Enter a valid time.'))323 raise ValidationError(self.error_messages['invalid']) 323 324 324 325 DEFAULT_DATETIME_INPUT_FORMATS = ( … … 360 361 # components: date and time. 361 362 if len(value) != 2: 362 raise ValidationError( ugettext(u'Enter a valid date/time.'))363 raise ValidationError(self.error_messages['invalid']) 363 364 value = '%s %s' % tuple(value) 364 365 for format in self.input_formats: … … 367 368 except ValueError: 368 369 continue 369 raise ValidationError( ugettext(u'Enter a valid date/time.'))370 raise ValidationError(self.error_messages['invalid']) 370 371 371 372 class RegexField(CharField): … … 376 377 'Enter a valid value' is too generic for you. 377 378 """ 379 # error_message is just kept for backwards compatibility: 380 if error_message: 381 error_messages = kwargs.get('error_messages') or {} 382 error_messages['invalid'] = error_message 383 kwargs['error_messages'] = error_messages 378 384 super(RegexField, self).__init__(max_length, min_length, *args, **kwargs) 379 385 if isinstance(regex, basestring): 380 386 regex = re.compile(regex) 381 387 self.regex = regex 382 self.error_message = error_message or ugettext(u'Enter a valid value.')383 388 384 389 def clean(self, value): … … 391 396 return value 392 397 if not self.regex.search(value): 393 raise ValidationError(self.error_message )398 raise ValidationError(self.error_messages['invalid']) 394 399 return value 395 400 … … 405 410 406 411 def __init__(self, max_length=None, min_length=None, *args, **kwargs): 407 RegexField.__init__(self, email_re, max_length, min_length, 408 ugettext(u'Enter a valid e-mail address.'), *args,**kwargs)412 RegexField.__init__(self, email_re, max_length, min_length, *args, 413 **kwargs) 409 414 410 415 try: … … 446 451 f = UploadedFile(data['filename'], data['content']) 447 452 except TypeError: 448 raise ValidationError( ugettext(u"No file was submitted. Check the encoding type on the form."))453 raise ValidationError(self.error_messages['invalid']) 449 454 except KeyError: 450 raise ValidationError( ugettext(u"No file was submitted."))455 raise ValidationError(self.error_messages['missing']) 451 456 if not f.content: 452 raise ValidationError( ugettext(u"The submitted file is empty."))457 raise ValidationError(self.error_messages['empty']) 453 458 return f 454 459 … … 478 483 trial_image.verify() 479 484 except Exception: # Python Imaging Library doesn't recognize it as an image 480 raise ValidationError( ugettext(u"Upload a valid image. The file you uploaded was either not an image or a corrupted image."))485 raise ValidationError(self.error_messages['invalid_image']) 481 486 return f 482 487 … … 497 502 def __init__(self, max_length=None, min_length=None, verify_exists=False, 498 503 validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs): 499 super(URLField, self).__init__(url_re, max_length, min_length, ugettext(u'Enter a valid URL.'), *args, **kwargs) 504 super(URLField, self).__init__(url_re, max_length, min_length, *args, 505 **kwargs) 500 506 self.verify_exists = verify_exists 501 507 self.user_agent = validator_user_agent … … 522 528 u = urllib2.urlopen(req) 523 529 except ValueError: 524 raise ValidationError( ugettext(u'Enter a valid URL.'))530 raise ValidationError(self.error_messages['invalid']) 525 531 except: # urllib2.URLError, httplib.InvalidURL, etc. 526 raise ValidationError( ugettext(u'This URL appears to be a broken link.'))532 raise ValidationError(self.error_messages['invalid_link']) 527 533 return value 528 534 … … 584 590 valid_values = set([smart_unicode(k) for k, v in self.choices]) 585 591 if value not in valid_values: 586 raise ValidationError( ugettext(u'Select a valid choice. That choice is not one of the available choices.'))592 raise ValidationError(self.error_messages['invalid_choice'] % {'value': value}) 587 593 return value 588 594 … … 600 606 """ 601 607 if self.required and not value: 602 raise ValidationError( ugettext(u'This field is required.'))608 raise ValidationError(self.error_messages['required']) 603 609 elif not self.required and not value: 604 610 return [] 605 611 if not isinstance(value, (list, tuple)): 606 raise ValidationError( ugettext(u'Enter a list of values.'))612 raise ValidationError(self.error_messages['invalid_list']) 607 613 new_value = [smart_unicode(val) for val in value] 608 614 # Validate that each value in the value list is in self.choices. … … 610 616 for val in new_value: 611 617 if val not in valid_values: 612 raise ValidationError( ugettext(u'Select a valid choice. %s is not one of the available choices.') % val)618 raise ValidationError(self.error_messages['invalid_choice'] % {'value': val}) 613 619 return new_value 614 620 … … 680 686 if not value or not [v for v in value if v not in EMPTY_VALUES]: 681 687 if self.required: 682 raise ValidationError( ugettext(u'This field is required.'))688 raise ValidationError(self.error_messages['required']) 683 689 else: 684 690 return self.compress([]) 685 691 else: 686 raise ValidationError( ugettext(u'Enter a list of values.'))692 raise ValidationError(self.error_messages['invalid']) 687 693 for i, field in enumerate(self.fields): 688 694 try: … … 691 697 field_value = None 692 698 if self.required and field_value in EMPTY_VALUES: 693 raise ValidationError( ugettext(u'This field is required.'))699 raise ValidationError(self.error_messages['required']) 694 700 try: 695 701 clean_data.append(field.clean(field_value)) … … 721 727 722 728 def __init__(self, *args, **kwargs): 723 fields = (DateField(), TimeField()) 729 errors = self.default_error_messages.copy() 730 if 'error_messages' in kwargs: 731 errors.update(kwargs['error_messages']) 732 fields = ( 733 DateField(error_messages={'invalid': errors['invalid_date']}), 734 TimeField(error_messages={'invalid': errors['invalid_time']}), 735 ) 724 736 super(SplitDateTimeField, self).__init__(fields, *args, **kwargs) 725 737 … … 729 741 # (possible if SplitDateTimeField has required=False). 730 742 if data_list[0] in EMPTY_VALUES: 731 raise ValidationError( ugettext(u'Enter a valid date.'))743 raise ValidationError(self.error_messages['invalid_date']) 732 744 if data_list[1] in EMPTY_VALUES: 733 raise ValidationError( ugettext(u'Enter a valid time.'))745 raise ValidationError(self.error_messages['invalid_time']) 734 746 return datetime.datetime.combine(*data_list) 735 747 return None … … 743 755 744 756 def __init__(self, *args, **kwargs): 745 RegexField.__init__(self, ipv4_re, 746 error_message=ugettext(u'Enter a valid IPv4 address.'), 747 *args, **kwargs) 748 757 super(IPAddressField, self).__init__(ipv4_re, *args, **kwargs) django/branches/queryset-refactor/django/newforms/util.py
r6690 r6693 47 47 return u'\n'.join([u'* %s' % force_unicode(e) for e in self]) 48 48 49 def __repr__(self): 50 return repr([force_unicode(e) for e in self]) 51 49 52 class ValidationError(Exception): 50 53 def __init__(self, message): 51 "ValidationError can be passed a string or a list." 54 """ 55 ValidationError can be passed any object that can be printed (usually 56 a string) or a list of objects. 57 """ 52 58 if isinstance(message, list): 53 59 self.messages = ErrorList([smart_unicode(msg) for msg in message]) 54 60 else: 55 assert isinstance(message, (basestring, Promise)), ("%s should be a basestring or lazy translation" % repr(message))56 61 message = smart_unicode(message) 57 62 self.messages = ErrorList([message]) … … 63 68 # See http://www.python.org/doc/current/tut/node10.html#handling 64 69 return repr(self.messages) 65 django/branches/queryset-refactor/django/test/testcases.py
r6690 r6693 151 151 " error '%s' (actual errors: %s)" % 152 152 (field, form, i, err, 153 list(field_errors)))153 repr(field_errors))) 154 154 elif field in context[form].fields: 155 155 self.fail("The field '%s' on form '%s' in context %d" django/branches/queryset-refactor/docs/newforms.txt
r6597 r6693 1079 1079 <p>Cc myself: <input type="checkbox" name="cc_myself" /></p> 1080 1080 1081 ``error_messages`` 1082 ~~~~~~~~~~~~~~~~~~ 1083 1084 **New in Django development version** 1085 1086 The ``error_messages`` argument lets you override the default messages which the 1087 field will raise. Pass in a dictionary with keys matching the error messages you 1088 want to override. For example:: 1089 1090 >>> generic = forms.CharField() 1091 >>> generic.clean('') 1092 Traceback (most recent call last): 1093 ... 1094 ValidationError: [u'This field is required.'] 1095 1096 >>> name = forms.CharField(error_messages={'required': 'Please enter your name'}) 1097 >>> name.clean('') 1098 Traceback (most recent call last): 1099 ... 1100 ValidationError: [u'Please enter your name'] 1101 1102 In the `built-in Field classes`_ section below, each Field defines the error 1103 message keys it uses. 1104 1081 1105 Dynamic initial values 1082 1106 ---------------------- … … 1144 1168 * Validates that the check box is checked (i.e. the value is ``True``) if 1145 1169 the field has ``required=True``. 1170 * Error message keys: ``required`` 1146 1171 1147 1172 **New in Django development version:** The empty value for a ``CheckboxInput`` … … 1163 1188 * Validates ``max_length`` or ``min_length``, if they are provided. 1164 1189 Otherwise, all inputs are valid. 1190 * Error message keys: ``required``, ``max_length``, ``min_length`` 1165 1191 1166 1192 Has two optional arguments for validation, ``max_length`` and ``min_length``. … … 1175 1201 * Normalizes to: A Unicode object. 1176 1202 * Validates that the given value exists in the list of choices. 1203 * Error message keys: ``required``, ``invalid_choice`` 1177 1204 1178 1205 Takes one extra argument, ``choices``, which is an iterable (e.g., a list or … … 1187 1214 * Validates that the given value is either a ``datetime.date``, 1188 1215 ``datetime.datetime`` or string formatted in a particular date format. 1216 * Error message keys: ``required``, ``invalid`` 1189 1217 1190 1218 Takes one optional argument, ``input_formats``, which is a list of formats used … … 1207 1235 * Validates that the given value is either a ``datetime.datetime``, 1208 1236 ``datetime.date`` or string formatted in a particular datetime format. 1237 * Error message keys: ``required``, ``invalid`` 1209 1238 1210 1239 Takes one optional argument, ``input_formats``, which is a list of formats used … … 1236 1265 * Validates that the given value is a decimal. Leading and trailing 1237 1266 whitespace is ignored. 1267 * Error message keys: ``required``, ``invalid``, ``max_value``, 1268 ``min_value``, ``max_digits``, ``max_decimal_places``, 1269 ``max_whole_digits`` 1238 1270 1239 1271 Takes four optional arguments: ``max_value``, ``min_value``, ``max_digits``, … … 1252 1284 * Validates that the given value is a valid e-mail address, using a 1253 1285 moderately complex regular expression. 1286 * Error message keys: ``required``, ``invalid`` 1254 1287 1255 1288 Has two optional arguments for validation, ``max_length`` and ``min_length``. … … 1267 1300 and file name into a single object. 1268 1301 * Validates that non-empty file data has been bound to the form. 1302 * Error message keys: ``required``, ``invalid``, ``missing``, ``empty`` 1269 1303 1270 1304 An ``UploadedFile`` object has two attributes: … … 1297 1331 * Validates that file data has been bound to the form, and that the 1298 1332 file is of an image format understood by PIL. 1333 * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``, 1334 ``invalid_image`` 1299 1335 1300 1336 Using an ImageField requires that the `Python Imaging Library`_ is installed. … … 1313 1349 * Validates that the given value is an integer. Leading and trailing 1314 1350 whitespace is allowed, as in Python's ``int()`` function. 1351 * Error message keys: ``required``, ``invalid``, ``max_value``, 1352 ``min_value`` 1315 1353 1316 1354 Takes two optional arguments for validation, ``max_value`` and ``min_value``. … … 1325 1363 * Validates that the given value is a valid IPv4 address, using a regular 1326 1364 expression. 1365 * Error message keys: ``required``, ``invalid`` 1327 1366 1328 1367 ``MultipleChoiceField`` … … 1334 1373 * Validates that every value in the given list of values exists in the list 1335 1374 of choices. 1375 * Error message keys: ``required``, ``invalid_choice``, ``invalid_list`` 1336 1376 1337 1377 Takes one extra argument, ``choices``, which is an iterable (e.g., a list or … … 1354 1394 * Validates that the given value matches against a certain regular 1355 1395 expression. 1396 * Error message keys: ``required``, ``invalid`` 1356 1397 1357 1398 Takes one required argument, ``regex``, which is a regular expression specified … … 1365 1406 ``max_length`` Ensures the string has at most this many characters. 1366 1407 ``min_length`` Ensures the string has at least this many characters. 1367 ``error_message`` Error message to return for failed validation. If no1368 message is provided, a generic error message will be1369 used.1370 1408 ====================== ===================================================== 1409 1410 The optional argument ``error_message`` is also accepted for backwards 1411 compatibility. The preferred way to provide an error message is to use the 1412 ``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key 1413 and the error message as the value. 1371 1414 1372 1415 ``TimeField`` … … 1378 1421 * Validates that the given value is either a ``datetime.time`` or string 1379 1422 formatted in a particular time format. 1423 * Error message keys: ``required``, ``invalid`` 1380 1424 1381 1425 Takes one optional argument, ``input_formats``, which is a list of formats used … … 1394 1438 * Normalizes to: A Unicode object. 1395 1439 * Validates that the given value is a valid URL. 1440 * Error message keys: ``required``, ``invalid``, ``invalid_link`` 1396 1441 1397 1442 Takes the following optional arguments:
