Ticket #12986: 12986-2.diff

File 12986-2.diff, 5.0 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{4})',
     56                        '%m': r'(?P<m>\d\d?)',
     57                        '%d': r'(?P<d>\d\d?)'
     58                    }
     59                    re_str = input_format
     60                    for k, v in f_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):
  • tests/regressiontests/forms/widgets.py

     
    12671267>>> deactivate()
    12681268>>> settings.USE_L10N = False
    12691269
     1270
     1271# SelectDateWidget
     1272>>> from django.forms.extras import  SelectDateWidget
     1273>>> w = SelectDateWidget()
     1274>>> w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date')
     1275'2010-8-13'
     1276>>> res = w.render('date', '2010-08-13')
     1277>>> u'<option value="13" selected="selected">13</option>' in res
     1278True
     1279>>> u'<option value="2010" selected="selected">2010</option>' in res
     1280True
     1281>>> u'<option value="8" selected="selected">August</option>' in res
     1282True
     1283>>> from django.utils import  translation
     1284>>> translation.activate('nl')
     1285>>> from django.conf import  settings
     1286>>> settings.USE_L10N=True
     1287>>> w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date')
     1288'13-8-2010'
     1289>>> res = w.render('date', '13-08-2010')
     1290>>> u'<option value="13" selected="selected">13</option>' in res
     1291True
     1292>>> u'<option value="2010" selected="selected">2010</option>' in res
     1293True
     1294>>> u'<option value="8" selected="selected">augustus</option>' in res
     1295True
     1296>>> w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date')
     1297'13-8-2010'
     1298>>> res = w.render('date', '31-2-2010')
     1299>>> u'<option value="31" selected="selected">31</option>' in res
     1300True
     1301>>> u'<option value="2010" selected="selected">2010</option>' in res
     1302True
     1303>>> u'<option value="2" selected="selected">februari</option>' in res
     1304True
    12701305"""
    12711306
    12721307
Back to Top