Ticket #2443: durationfield.4.diff
File durationfield.4.diff, 6.5 KB (added by , 17 years ago) |
---|
-
django/db/models/fields/__init__.py
636 676 defaults.update(kwargs) 637 677 return super(DecimalField, self).formfield(**defaults) 638 678 679 class DurationField(Field): 680 max_digits, decimal_places = 20, 6 681 682 def get_internal_type(self): 683 return "DecimalField" 684 685 def contribute_to_class(self, cls, name): 686 super(DurationField, self).contribute_to_class(cls, name) 687 setattr(cls, name, self.lazy_attribute(datetime.timedelta, self.create)) 688 689 def get_db_prep_save(self, value): 690 return str(value.days * 24 * 3600 + value.seconds + float(value.microseconds) / 1000000) 691 692 def to_python(self, value): 693 if isinstance(value, datetime.timedelta): 694 return value 695 try: 696 return datetime.timedelta(seconds=float(value)) 697 except (TypeError, ValueError): 698 raise validators.ValidationError('This value must be a real number.') 699 except OverflowError: 700 raise validators.ValidationError('The maximum allowed value is %s' % datetime.timedelta.max) 701 702 def create(self, value): 703 return datetime.timedelta(seconds=float(value) or 0) 704 705 def flatten_data(self, follow, obj=None): 706 val = self._get_val_from_obj(obj) 707 if val is None or val is '': 708 return '' 709 return {self.attname: self.get_db_prep_save(val)} 710 711 def formfield(self, form_class=forms.SplitDurationField, **kwargs): 712 return super(DurationField, self).formfield(form_class, **kwargs) 713 714 def get_manipulator_field_objs(self): 715 return [curry(oldforms.DecimalField, max_digits=self.max_digits, decimal_places=self.decimal_places)] 716 639 717 class EmailField(CharField): 640 718 def __init__(self, *args, **kwargs): 641 719 kwargs['maxlength'] = 75 -
django/newforms/fields.py
10 10 from django.utils.encoding import smart_unicode 11 11 12 12 from util import ErrorList, ValidationError 13 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple 13 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, SplitDurationWidget 14 14 15 15 __all__ = ( 16 16 'Field', 'CharField', 'IntegerField', … … 20 20 'RegexField', 'EmailField', 'URLField', 'BooleanField', 21 21 'ChoiceField', 'NullBooleanField', 'MultipleChoiceField', 22 22 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', 23 'SplitDateTimeField', 23 'SplitDateTimeField', 'SplitDurationField', 24 24 ) 25 25 26 26 # These values, if given to to_python(), will trigger the self.required check. … … 560 560 if data_list: 561 561 return datetime.datetime.combine(*data_list) 562 562 return None 563 564 class SplitDurationField(MultiValueField): 565 widget = SplitDurationWidget 566 567 def __init__(self, *args, **kwargs): 568 fields = ( 569 IntegerField(label='Days', max_value=999999999, min_value=-999999999), 570 IntegerField(label='Hours', max_value=23, min_value=0), 571 IntegerField(label='Minutes', max_value=59, min_value=0), 572 IntegerField(label='Seconds', max_value=59, min_value=0), 573 IntegerField(label='Microseconds', max_value=999999, min_value=0), 574 ) 575 super(SplitDurationField, self).__init__(fields, *args, **kwargs) 576 577 def compress(self, data_list): 578 if data_list == [None] * 5: 579 raise ValidationError(gettext(u'This field is required.')) 580 if data_list: 581 return datetime.timedelta( 582 days=data_list[0] or 0, 583 hours=data_list[1] or 0, 584 minutes=data_list[2] or 0, 585 seconds=data_list[3] or 0, 586 microseconds=data_list[4] or 0, 587 ) 588 return None -
django/newforms/widgets.py
21 21 'FileInput', 'Textarea', 'CheckboxInput', 22 22 'Select', 'NullBooleanSelect', 'SelectMultiple', 'RadioSelect', 23 23 'CheckboxSelectMultiple', 'MultiWidget', 'SplitDateTimeWidget', 24 'SplitDurationWidget', 24 25 ) 25 26 26 27 class Widget(object): … … 374 375 if value: 375 376 return [value.date(), value.time()] 376 377 return [None, None] 378 379 class SplitDurationWidget(MultiWidget): 380 def __init__(self, attrs=None): 381 attrs = attrs or {} 382 widgets = ( 383 TextInput(attrs=dict(attrs, size=4, maxlength=10, title='Days')), 384 TextInput(attrs=dict(attrs, size=1, maxlength=2, title='Hours')), 385 TextInput(attrs=dict(attrs, size=1, maxlength=2, title='Minutes')), 386 TextInput(attrs=dict(attrs, size=1, maxlength=2, title='Seconds')), 387 TextInput(attrs=dict(attrs, size=5, maxlength=6, title='Microseconds')), 388 ) 389 super(SplitDurationWidget, self).__init__(widgets, attrs) 390 391 def decompress(self, value): 392 if value: 393 hours, seconds = divmod(value.seconds, 3600) 394 minutes, seconds = divmod(seconds, 60) 395 return [value.days, hours, minutes, seconds, value.microseconds] 396 return [None, None, None, None, None] 397 398 def format_output(self, rendered_widgets): 399 return u'%s days, %s : %s : %s . %s' % tuple(rendered_widgets) -
docs/model-api.txt
213 213 214 214 The admin represents this as an ``<input type="text">`` (a single-line input). 215 215 216 ``DurationField`` 217 ~~~~~~~~~~~~~~~~~ 218 219 **New in Django development version** 220 221 A span of time, represented in Python by a ``timedelta`` instance. 222 223 The admin represents this as an ``<input type="text">`` (a single-line input), 224 with its value representing the number of seconds in the duration. Fractional 225 values are allowed, with a millisecond precision. 226 216 227 ``EmailField`` 217 228 ~~~~~~~~~~~~~~ 218 229