Ticket #5714: 5714.diff
File 5714.diff, 9.2 KB (added by , 14 years ago) |
---|
-
django/forms/fields.py
diff --git a/django/forms/fields.py b/django/forms/fields.py index 4d7728f..eb6ef22 100644
a b from django.core import validators 19 19 import django.utils.copycompat as copy 20 20 from django.utils import formats 21 21 from django.utils.translation import ugettext_lazy as _ 22 from django.utils.encoding import smart_unicode, smart_str 22 from django.utils.encoding import smart_unicode, smart_str, force_unicode 23 23 from django.utils.functional import lazy 24 24 25 25 # Provide this import for backwards compatibility. … … class DecimalField(Field): 336 336 raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) 337 337 return value 338 338 339 class DateField(Field): 339 class BaseTemporalField(Field): 340 def __init__(self, input_formats=None, *args, **kwargs): 341 super(BaseTemporalField, self).__init__(*args, **kwargs) 342 self.input_formats = input_formats 343 344 def to_python(self, value): 345 # Try to coerce the value to unicode. 346 unicode_value = force_unicode(value, strings_only=True) 347 if isinstance(unicode_value, unicode): 348 value = unicode_value.strip() 349 # If empty, return None 350 if value in validators.EMPTY_VALUES: 351 return None 352 # If unicode, try to strptime against each import format. 353 if isinstance(value, unicode): 354 for format in self.get_input_formats(): 355 try: 356 return self.strptime(value, format) 357 except ValueError: 358 continue 359 raise ValidationError(self.error_messages['invalid']) 360 361 def get_input_formats(self): 362 return self.input_formats or [] 363 364 def strptime(self, value, format): 365 raise NotImplementedError('Subclasses must define this method.') 366 367 class DateField(BaseTemporalField): 340 368 widget = DateInput 341 369 default_error_messages = { 342 370 'invalid': _(u'Enter a valid date.'), 343 371 } 344 372 345 def __init__(self, input_formats=None, *args, **kwargs):346 super(DateField, self).__init__(*args, **kwargs)347 self.input_formats = input_formats348 349 373 def to_python(self, value): 350 374 """ 351 375 Validates that the input can be converted to a date. Returns a Python 352 376 datetime.date object. 353 377 """ 354 if value in validators.EMPTY_VALUES:355 return None356 378 if isinstance(value, datetime.datetime): 357 379 return value.date() 358 380 if isinstance(value, datetime.date): 359 381 return value 360 for format in self.input_formats or formats.get_format('DATE_INPUT_FORMATS'): 361 try: 362 return datetime.date(*time.strptime(value, format)[:3]) 363 except ValueError: 364 continue 365 raise ValidationError(self.error_messages['invalid']) 382 return super(DateField, self).to_python(value) 383 384 def get_input_formats(self): 385 return self.input_formats or formats.get_format('DATE_INPUT_FORMATS') 386 387 def strptime(self, value, format): 388 return datetime.date(*time.strptime(value, format)[:3]) 366 389 367 class TimeField( Field):390 class TimeField(BaseTemporalField): 368 391 widget = TimeInput 369 392 default_error_messages = { 370 393 'invalid': _(u'Enter a valid time.') 371 394 } 372 395 373 def __init__(self, input_formats=None, *args, **kwargs):374 super(TimeField, self).__init__(*args, **kwargs)375 self.input_formats = input_formats376 377 396 def to_python(self, value): 378 397 """ 379 398 Validates that the input can be converted to a time. Returns a Python 380 399 datetime.time object. 381 400 """ 382 if value in validators.EMPTY_VALUES:383 return None384 401 if isinstance(value, datetime.time): 385 402 return value 386 for format in self.input_formats or formats.get_format('TIME_INPUT_FORMATS'): 387 try: 388 return datetime.time(*time.strptime(value, format)[3:6]) 389 except ValueError: 390 continue 391 raise ValidationError(self.error_messages['invalid']) 403 return super(TimeField, self).to_python(value) 404 405 def get_input_formats(self): 406 return self.input_formats or formats.get_format('TIME_INPUT_FORMATS') 407 408 def strptime(self, value, format): 409 return datetime.time(*time.strptime(value, format)[3:6]) 392 410 393 class DateTimeField( Field):411 class DateTimeField(BaseTemporalField): 394 412 widget = DateTimeInput 395 413 default_error_messages = { 396 414 'invalid': _(u'Enter a valid date/time.'), 397 415 } 398 416 399 def __init__(self, input_formats=None, *args, **kwargs):400 super(DateTimeField, self).__init__(*args, **kwargs)401 self.input_formats = input_formats402 403 417 def to_python(self, value): 404 418 """ 405 419 Validates that the input can be converted to a datetime. Returns a 406 420 Python datetime.datetime object. 407 421 """ 408 if value in validators.EMPTY_VALUES:409 return None410 422 if isinstance(value, datetime.datetime): 411 423 return value 412 424 if isinstance(value, datetime.date): … … class DateTimeField(Field): 419 431 if value[0] in validators.EMPTY_VALUES and value[1] in validators.EMPTY_VALUES: 420 432 return None 421 433 value = '%s %s' % tuple(value) 422 for format in self.input_formats or formats.get_format('DATETIME_INPUT_FORMATS'): 423 try: 424 return datetime.datetime(*time.strptime(value, format)[:6]) 425 except ValueError: 426 continue 427 raise ValidationError(self.error_messages['invalid']) 434 return super(DateTimeField, self).to_python(value) 435 436 def get_input_formats(self): 437 return (self.input_formats or 438 formats.get_format('DATETIME_INPUT_FORMATS')) 439 440 def strptime(self, value, format): 441 return datetime.datetime(*time.strptime(value, format)[:6]) 428 442 429 443 class RegexField(CharField): 430 444 def __init__(self, regex, max_length=None, min_length=None, error_message=None, *args, **kwargs): -
tests/regressiontests/forms/tests/fields.py
diff --git a/tests/regressiontests/forms/tests/fields.py b/tests/regressiontests/forms/tests/fields.py index 576a9c3..dad6003 100644
a b class FieldsTests(TestCase): 333 333 self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '10/25/2006') 334 334 self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid date.']", f.clean, '10/25/06') 335 335 336 def test_datefield_4(self): 337 # Test whitespace stripping behavior (#5714) 338 f = DateField() 339 self.assertEqual(datetime.date(2006, 10, 25), f.clean(' 10/25/2006 ')) 340 self.assertEqual(datetime.date(2006, 10, 25), f.clean(' 10/25/06 ')) 341 self.assertEqual(datetime.date(2006, 10, 25), f.clean(' Oct 25 2006 ')) 342 self.assertEqual(datetime.date(2006, 10, 25), f.clean(' October 25 2006 ')) 343 self.assertEqual(datetime.date(2006, 10, 25), f.clean(' October 25, 2006 ')) 344 self.assertEqual(datetime.date(2006, 10, 25), f.clean(' 25 October 2006 ')) 345 self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, ' ') 346 336 347 # TimeField ################################################################### 337 348 338 349 def test_timefield_1(self): … … class FieldsTests(TestCase): 352 363 self.assertEqual(datetime.time(16, 25), f.clean('4:25 PM')) 353 364 self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid time.']", f.clean, '14:30:45') 354 365 366 def test_timefield_3(self): 367 f = TimeField() 368 # Test whitespace stripping behavior (#5714) 369 self.assertEqual(datetime.time(14, 25), f.clean(' 14:25 ')) 370 self.assertEqual(datetime.time(14, 25, 59), f.clean(' 14:25:59 ')) 371 self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, ' ') 372 355 373 # DateTimeField ############################################################### 356 374 357 375 def test_datetimefield_1(self): … … class FieldsTests(TestCase): 391 409 self.assertEqual(None, f.clean('')) 392 410 self.assertEqual('None', repr(f.clean(''))) 393 411 412 def test_datetimefield_4(self): 413 f = DateTimeField() 414 # Test whitespace stripping behavior (#5714) 415 self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean(' 2006-10-25 14:30:45 ')) 416 self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(' 2006-10-25 ')) 417 self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean(' 10/25/2006 14:30:45 ')) 418 self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30), f.clean(' 10/25/2006 14:30 ')) 419 self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(' 10/25/2006 ')) 420 self.assertEqual(datetime.datetime(2006, 10, 25, 14, 30, 45), f.clean(' 10/25/06 14:30:45 ')) 421 self.assertEqual(datetime.datetime(2006, 10, 25, 0, 0), f.clean(' 10/25/06 ')) 422 self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, ' ') 423 394 424 # RegexField ################################################################## 395 425 396 426 def test_regexfield_1(self):