Django

Code

Ticket #8962: 8962-datetime-format-r8983.2.diff

File 8962-datetime-format-r8983.2.diff, 14.6 kB (added by mrmachine, 4 months ago)

Set default date/time format for SplitDateTimeWidget as class attribute, so it can be overridden in a subclass.

  • django/forms/fields.py

    old new  
    2828from django.utils.encoding import smart_unicode, smart_str 
    2929 
    3030from util import ErrorList, ValidationError 
    31 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput, TimeInput, SplitHiddenDateTimeWidget 
     31from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput, SplitDateTimeWidget, SplitHiddenDateTimeWidget 
    3232from django.core.files.uploadedfile import SimpleUploadedFile as UploadedFile 
    3333 
    3434__all__ = ( 
     
    283283) 
    284284 
    285285class DateField(Field): 
     286    widget = DateInput 
    286287    default_error_messages = { 
    287288        'invalid': _(u'Enter a valid date.'), 
    288289    } 
     
    843844        self.widget.choices = self.choices 
    844845 
    845846class SplitDateTimeField(MultiValueField): 
     847    widget = SplitDateTimeWidget 
    846848    hidden_widget = SplitHiddenDateTimeWidget 
    847849    default_error_messages = { 
    848850        'invalid_date': _(u'Enter a valid date.'), 
    849851        'invalid_time': _(u'Enter a valid time.'), 
    850852    } 
    851853 
    852     def __init__(self, *args, **kwargs): 
     854    def __init__(self, input_date_formats=None, input_time_formats=None, *args, **kwargs): 
    853855        errors = self.default_error_messages.copy() 
    854856        if 'error_messages' in kwargs: 
    855857            errors.update(kwargs['error_messages']) 
    856858        fields = ( 
    857             DateField(error_messages={'invalid': errors['invalid_date']}), 
    858             TimeField(error_messages={'invalid': errors['invalid_time']}), 
     859            DateField(input_formats=input_date_formats, error_messages={'invalid': errors['invalid_date']}), 
     860            TimeField(input_formats=input_time_formats, error_messages={'invalid': errors['invalid_time']}), 
    859861        ) 
    860862        super(SplitDateTimeField, self).__init__(fields, *args, **kwargs) 
    861863 
  • django/forms/widgets.py

    old new  
    2323__all__ = ( 
    2424    'Media', 'MediaDefiningClass', 'Widget', 'TextInput', 'PasswordInput', 
    2525    'HiddenInput', 'MultipleHiddenInput', 
    26     'FileInput', 'DateTimeInput', 'TimeInput', 'Textarea', 'CheckboxInput', 
     26    'FileInput', 'DateInput', 'DateTimeInput', 'TimeInput', 'Textarea', 'CheckboxInput', 
    2727    'Select', 'NullBooleanSelect', 'SelectMultiple', 'RadioSelect', 
    2828    'CheckboxSelectMultiple', 'MultiWidget', 
    2929    'SplitDateTimeWidget', 
     
    286286        return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), 
    287287                conditional_escape(force_unicode(value)))) 
    288288 
     289class DateInput(Input): 
     290    input_type = 'text' 
     291    format = '%Y-%m-%d'     # '2006-10-25' 
     292 
     293    def __init__(self, attrs=None, format=None): 
     294        super(DateInput, self).__init__(attrs) 
     295        if format: 
     296            self.format = format 
     297 
     298    def render(self, name, value, attrs=None): 
     299        if value is None: 
     300            value = '' 
     301        elif hasattr(value, 'strftime'): 
     302            value = datetime_safe.new_date(value) 
     303            value = value.strftime(self.format) 
     304        return super(DateInput, self).render(name, value, attrs) 
     305 
    289306class DateTimeInput(Input): 
    290307    input_type = 'text' 
    291308    format = '%Y-%m-%d %H:%M:%S'     # '2006-10-25 14:30:59' 
     
    305322 
    306323class TimeInput(Input): 
    307324    input_type = 'text' 
     325    format = '%H:%M:%S'     # '14:30:59' 
    308326 
     327    def __init__(self, attrs=None, format=None): 
     328        super(TimeInput, self).__init__(attrs) 
     329        if format: 
     330            self.format = format 
     331 
    309332    def render(self, name, value, attrs=None): 
    310333        if value is None: 
    311334            value = '' 
    312         elif isinstance(value, time): 
    313             value = value.replace(microsecond=0
     335        elif hasattr(value, 'strftime'): 
     336            value = value.strftime(self.format
    314337        return super(TimeInput, self).render(name, value, attrs) 
    315338 
    316339class CheckboxInput(Widget): 
     
    655678    """ 
    656679    A Widget that splits datetime input into two <input type="text"> boxes. 
    657680    """ 
    658     def __init__(self, attrs=None): 
    659         widgets = (TextInput(attrs=attrs), TextInput(attrs=attrs)) 
     681    date_format = DateInput.format 
     682    time_format = TimeInput.format 
     683 
     684    def __init__(self, attrs=None, date_format=None, time_format=None): 
     685        if date_format: 
     686            self.date_format = date_format 
     687        if time_format: 
     688            self.time_format = time_format 
     689        widgets = (DateInput(attrs=attrs, format=self.date_format), 
     690                   TimeInput(attrs=attrs, format=self.time_format)) 
    660691        super(SplitDateTimeWidget, self).__init__(widgets, attrs) 
    661692 
    662693    def decompress(self, value): 
     
    671702    def __init__(self, attrs=None): 
    672703        widgets = (HiddenInput(attrs=attrs), HiddenInput(attrs=attrs)) 
    673704        super(SplitDateTimeWidget, self).__init__(widgets, attrs) 
    674  
  • django/contrib/localflavor/generic/forms.py

    old new  
    3636    def __init__(self, input_formats=None, *args, **kwargs): 
    3737        input_formats = input_formats or DEFAULT_DATETIME_INPUT_FORMATS 
    3838        super(DateTimeField, self).__init__(input_formats=input_formats, *args, **kwargs) 
     39 
     40class SplitDateTimeField(forms.SplitDateTimeField): 
     41    """ 
     42    Split date and time input fields which use non-US date and time input 
     43    formats by default. 
     44    """ 
     45    def __init__(self, input_date_formats=None, input_time_formats=None, *args, **kwargs): 
     46        input_date_formats = input_date_formats or DEFAULT_DATE_INPUT_FORMATS 
     47        super(SplitDateTimeField, self).__init__(input_date_formats=input_date_formats, 
     48                                                 input_time_formats=input_time_formats, *args, **kwargs) 
  • tests/regressiontests/forms/widgets.py

    old new  
    10711071>>> w.render('date', datetime.datetime(2006, 1, 10, 7, 30)) 
    10721072u'<input type="text" class="pretty" value="2006-01-10" name="date_0" /><input type="text" class="pretty" value="07:30:00" name="date_1" />' 
    10731073 
     1074Use 'date_format' and 'time_format' to change the way a value is displayed. 
     1075>>> w = SplitDateTimeWidget(date_format='%d/%m/%Y', time_format='%H:%M') 
     1076>>> w.render('date', datetime.datetime(2006, 1, 10, 7, 30)) 
     1077u'<input type="text" name="date_0" value="10/01/2006" /><input type="text" name="date_1" value="07:30" />' 
     1078 
    10741079>>> w._has_changed(datetime.datetime(2008, 5, 5, 12, 40, 00), [u'2008-05-05', u'12:40:00']) 
    10751080False 
    10761081>>> w._has_changed(datetime.datetime(2008, 5, 5, 12, 40, 00), [u'2008-05-05', u'12:41:00']) 
     
    10931098>>> w.render('date', datetime.datetime(2007, 9, 17, 12, 51)) 
    10941099u'<input type="text" name="date" value="2007-09-17 12:51:00" />' 
    10951100 
     1101Use 'format' to change the way a value is displayed. 
     1102>>> w = DateTimeInput(format='%d/%m/%Y %H:%M') 
     1103>>> w.render('date', d) 
     1104u'<input type="text" name="date" value="17/09/2007 12:51" />' 
     1105 
     1106# DateInput ################################################################### 
     1107 
     1108>>> w = DateInput() 
     1109>>> w.render('date', None) 
     1110u'<input type="text" name="date" />' 
     1111>>> d = datetime.date(2007, 9, 17) 
     1112>>> print d 
     11132007-09-17 
     1114 
     1115>>> w.render('date', d) 
     1116u'<input type="text" name="date" value="2007-09-17" />' 
     1117>>> w.render('date', datetime.date(2007, 9, 17)) 
     1118u'<input type="text" name="date" value="2007-09-17" />' 
     1119 
     1120We should be able to initialize from a unicode value. 
     1121>>> w.render('date', u'2007-09-17') 
     1122u'<input type="text" name="date" value="2007-09-17" />' 
     1123 
     1124Use 'format' to change the way a value is displayed. 
     1125>>> w = DateInput(format='%d/%m/%Y') 
     1126>>> w.render('date', d) 
     1127u'<input type="text" name="date" value="17/09/2007" />' 
     1128 
    10961129# TimeInput ################################################################### 
    10971130 
    10981131>>> w = TimeInput() 
     
    11141147>>> w.render('time', u'13:12:11') 
    11151148u'<input type="text" name="time" value="13:12:11" />' 
    11161149 
     1150Use 'format' to change the way a value is displayed. 
     1151>>> w = TimeInput(format='%H:%M') 
     1152>>> w.render('time', t) 
     1153u'<input type="text" name="time" value="12:51" />' 
     1154 
    11171155# SplitHiddenDateTimeWidget ################################################### 
    11181156 
    11191157>>> from django.forms.widgets import SplitHiddenDateTimeWidget 
     
    11211159>>> w = SplitHiddenDateTimeWidget() 
    11221160>>> w.render('date', '') 
    11231161u'<input type="hidden" name="date_0" /><input type="hidden" name="date_1" />' 
     1162>>> d = datetime.datetime(2007, 9, 17, 12, 51, 34, 482548) 
     1163>>> print d 
     11642007-09-17 12:51:34.482548 
    11241165>>> w.render('date', d) 
    11251166u'<input type="hidden" name="date_0" value="2007-09-17" /><input type="hidden" name="date_1" value="12:51:34" />' 
    11261167>>> w.render('date', datetime.datetime(2007, 9, 17, 12, 51, 34)) 
  • AUTHORS

    old new  
    239239    Eugene Lazutkin <http://lazutkin.com/blog/> 
    240240    lcordier@point45.com 
    241241    Jeong-Min Lee <falsetru@gmail.com> 
     242    Tai Lee <real.human@mrmachine.net> 
    242243    Jannis Leidel <jl@websushi.org> 
    243244    Christopher Lenz <http://www.cmlenz.net/> 
    244245    lerouxb@gmail.com 
     
    278279    Aljosa Mohorovic <aljosa.mohorovic@gmail.com> 
    279280    Ramiro Morales <rm0@gmx.net> 
    280281    Eric Moritz <http://eric.themoritzfamily.com/> 
    281     mrmachine <real.human@mrmachine.net> 
    282282    Robin Munn <http://www.geekforgod.com/> 
    283283    James Murty 
    284284    msundstr 
  • docs/ref/contrib/localflavor.txt

    old new  
    6565    * `United States of America`_ 
    6666 
    6767The ``django.contrib.localflavor`` package also includes a ``generic`` subpackage, 
    68 containing useful code that is not specific to one particular country or 
    69 culture. Currently, it defines date and datetime input fields based on those 
    70 from :ref:`forms <topics-forms-index>`, but with non-US default formats. 
     68containing useful code that is not specific to one particular country or culture. 
     69Currently, it defines date, datetime and split datetime input fields based on 
     70those from :ref:`forms <topics-forms-index>`, but with non-US default formats. 
    7171Here's an example of how to use them:: 
    7272 
    7373    from django import forms 
  • docs/ref/forms/fields.txt

    old new  
    396396 
    397397.. class:: DateField(**kwargs) 
    398398 
    399     * Default widget: ``TextInput`` 
     399    * Default widget: ``DateInput`` 
    400400    * Empty value: ``None`` 
    401401    * Normalizes to: A Python ``datetime.date`` object. 
    402402    * Validates that the given value is either a ``datetime.date``, 
     
    418418    '%B %d %Y', '%B %d, %Y',            # 'October 25 2006', 'October 25, 2006' 
    419419    '%d %B %Y', '%d %B, %Y',            # '25 October 2006', '25 October, 2006' 
    420420 
     421.. versionchanged:: development version 
     422   The ``DateField`` previously used a ``TextInput`` widget by default. It now 
     423   uses a ``DateInput`` widget. 
     424 
    421425``DateTimeField`` 
    422426~~~~~~~~~~~~~~~~~ 
    423427 
     
    737741 
    738742.. class:: SplitDateTimeField(**kwargs) 
    739743 
     744    * Default widget: ``SplitDateTimeWidget`` 
     745    * Empty value: ``None`` 
     746    * Normalizes to: A Python ``datetime.datetime`` object. 
     747    * Validates that the given value is a ``datetime.datetime`` or string 
     748      formatted in a particular datetime format. 
     749    * Error message keys: ``required``, ``invalid`` 
     750 
     751Takes two optional arguments: 
     752 
     753.. attribute:: SplitDateTimeField.input_date_formats 
     754 
     755    A list of formats used to attempt to convert a string to a valid 
     756    ``datetime.date`` object. 
     757 
     758If no ``input_date_formats`` argument is provided, the default input formats 
     759for ``DateField`` are used. 
     760 
     761.. attribute:: SplitDateTimeField.input_time_formats 
     762 
     763    A list of formats used to attempt to convert a string to a valid 
     764    ``datetime.time`` object. 
     765 
     766If no ``input_time_formats`` argument is provided, the default input formats 
     767for ``TimeField`` are used. 
     768 
     769.. versionchanged:: development version 
     770   The ``SplitDateTimeField`` previously used two ``TextInput`` widgets by 
     771   default. The ``input_date_formats`` and ``input_time_formats`` arguments 
     772   are also new in the development version. 
     773 
    740774Fields which handle relationships 
    741775--------------------------------- 
    742776 
  • docs/ref/forms/widgets.txt

    old new  
    3636 
    3737    File upload input: ``<input type='file' ...>`` 
    3838 
     39.. class:: DateInput 
     40 
     41    .. versionadded:: development version 
     42 
     43    Date input as a simple text box: ``<input type='text' ...>`` 
     44 
     45    Takes one optional argument: 
     46     
     47    .. attribute:: DateInput.format 
     48 
     49        The format in which this field's initial value will be displayed. 
     50 
     51    If no ``format`` argument is provided, the default format is ``'%Y-%m-%d'``. 
     52 
    3953.. class:: DateTimeInput 
    4054 
    4155    .. versionadded:: 1.0 
    4256 
    4357    Date/time input as a simple text box: ``<input type='text' ...>`` 
    4458 
     59    Takes one optional argument: 
     60     
     61    .. attribute:: DateTimeInput.format 
     62     
     63        The format in which this field's initial value will be displayed. 
     64     
     65    If no ``format`` argument is provided, the default format is ``'%Y-%m-%d %H:%M:%S'``. 
     66 
     67.. class:: TimeInput 
     68 
     69    Time input as a simple text box: ``<input type='text' ...>`` 
     70 
     71    Takes one optional argument: 
     72     
     73    .. attribute:: TimeInput.format 
     74     
     75        The format in which this field's initial value will be displayed. 
     76     
     77    If no ``format`` argument is provided, the default format is ``'%H:%M:%S'``. 
     78 
     79    .. versionchanged:: development version 
     80       The ``format`` argument is new in the development version. 
     81 
    4582.. class:: Textarea 
    4683 
    4784    Text area: ``<textarea>...</textarea>`` 
     
    91128 
    92129.. class:: SplitDateTimeWidget 
    93130 
    94     Wrapper around two ``TextInput`` widgets: one for the date, and one for the 
    95     time. 
     131    Wrapper around two widgets: ``DateInput`` for the date, and ``TimeInput`` 
     132    for the time. 
    96133 
     134    Takes two optional arguments, ``date_format`` and ``time_format``, which 
     135    work just like the ``format`` argument for ``DateInput`` and ``TimeInput``. 
     136 
    97137Specifying widgets 
    98138------------------ 
    99139