Ticket #12986: 12986-3.diff

File 12986-3.diff, 5.1 KB (added by bmihelac, 5 years ago)
  • ../django/forms/extras/widgets.py

     
    1313
    1414__all__ = ('SelectDateWidget',)
    1515
    16 RE_DATE = re.compile(r'(\d{4})-(\d\d?)-(\d\d?)$')
    17 
    1816class SelectDateWidget(Widget):
    1917    """
    2018    A Widget that splits date input into three <select> boxes.
    2119
    2220    This also serves as an example of a Widget that has more than one HTML
    2321    element and hence implements value_from_datadict.
     22   
     23    If format localization is used (USE_L10N = True), combination of %Y, %m and %d directives in default
     24    input format is needed for invalid dates to be rendered.
    2425    """
    2526    none_value = (0, '---')
    2627    month_field = '%s_month'
     
    3637        else:
    3738            this_year = datetime.date.today().year
    3839            self.years = range(this_year, this_year+10)
    39 
     40           
    4041    def render(self, name, value, attrs=None):
    4142        try:
    4243            year_val, month_val, day_val = value.year, value.month, value.day
    4344        except AttributeError:
    4445            year_val = month_val = day_val = None
    4546            if isinstance(value, basestring):
    46                 match = RE_DATE.match(value)
    47                 if match:
    48                     year_val, month_val, day_val = [int(v) for v in match.groups()]
    49 
     47                input_format = get_format('DATE_INPUT_FORMATS')[0]
     48                try:
     49                    val = datetime.datetime.strptime(value, input_format)
     50                    year_val, month_val, day_val = val.year, val.month, val.day
     51                except ValueError:
     52                    # When selected day is invalid in month convert input format to regex and receive year, day, month values
     53                    # so the failed date still can be rendered.
     54                    format_to_re_dic = {
     55                        '%Y': r'(?P<y>\d+)?',
     56                        '%m': r'(?P<m>\d+?)?',
     57                        '%d': r'(?P<d>\d+?)?'
     58                    }
     59                    re_str = input_format
     60                    for k, v in format_to_re_dic.iteritems():
     61                        re_str = re_str.replace(k, v)                 
     62                    match = re.match('^' + re_str + '$', value)
     63                    if match:
     64                        year_val, month_val, day_val = int(match.group('y')), int(match.group('m')), int(match.group('d'))
    5065        choices = [(i, i) for i in self.years]
    5166        year_html = self.create_select(name, self.year_field, value, year_val, choices)
    5267        choices = MONTHS.items()
     
    8196        if y == m == d == "0":
    8297            return None
    8398        if y and m and d:
    84             if settings.USE_L10N:
    85                 input_format = get_format('DATE_INPUT_FORMATS')[0]
    86                 try:
    87                     date_value = datetime.date(int(y), int(m), int(d))
    88                 except ValueError:
    89                     pass
    90                 else:
    91                     return date_value.strftime(input_format)
    92             else:
    93                 return '%s-%s-%s' % (y, m, d)
     99            input_format = get_format('DATE_INPUT_FORMATS')[0]
     100            return input_format.replace('%Y', y).replace('%m', m).replace('%d', d)
    94101        return data.get(name, None)
    95102
    96103    def create_select(self, name, field, value, val, choices):
     
    98105            id_ = self.attrs['id']
    99106        else:
    100107            id_ = 'id_%s' % name
    101         if not (self.required and value):
    102             choices.insert(0, self.none_value)
     108        choices.insert(0, self.none_value)
    103109        local_attrs = self.build_attrs(id=field % id_)
    104110        s = Select(choices=choices)
    105111        select_html = s.render(field % name, val, local_attrs)
  • ../tests/regressiontests/forms/extra.py

     
    3643642008-04-01
    365365
    366366
     367USE_L10N tests
     368
     369>>> from django.utils import  translation
     370>>> translation.activate('nl')
     371>>> from django.conf import settings
     372>>> settings.USE_L10N=True
     373>>> w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date')
     374'13-8-2010'
     375>>> res = w.render('date', '13-08-2010')
     376>>> u'<option value="13" selected="selected">13</option>' in res
     377True
     378>>> u'<option value="2010" selected="selected">2010</option>' in res
     379True
     380>>> u'<option value="8" selected="selected">augustus</option>' in res
     381True
     382>>> w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date')
     383'13-8-2010'
     384>>> res = w.render('date', '31-2-2010')
     385>>> u'<option value="31" selected="selected">31</option>' in res
     386True
     387>>> u'<option value="2010" selected="selected">2010</option>' in res
     388True
     389>>> u'<option value="2" selected="selected">februari</option>' in res
     390True
     391>>> translation.deactivate()
     392
    367393# MultiWidget and MultiValueField #############################################
    368394# MultiWidgets are widgets composed of other widgets. They are usually
    369395# combined with MultiValueFields - a field that is composed of other fields.
Back to Top