web/lib/django/forms/extras/widgets.py
changeset 0 0d40e90630ef
child 29 cc9b7e14412b
equal deleted inserted replaced
-1:000000000000 0:0d40e90630ef
       
     1 """
       
     2 Extra HTML Widget classes
       
     3 """
       
     4 
       
     5 import datetime
       
     6 import re
       
     7 
       
     8 from django.forms.widgets import Widget, Select
       
     9 from django.utils.dates import MONTHS
       
    10 from django.utils.safestring import mark_safe
       
    11 
       
    12 __all__ = ('SelectDateWidget',)
       
    13 
       
    14 RE_DATE = re.compile(r'(\d{4})-(\d\d?)-(\d\d?)$')
       
    15 
       
    16 class SelectDateWidget(Widget):
       
    17     """
       
    18     A Widget that splits date input into three <select> boxes.
       
    19 
       
    20     This also serves as an example of a Widget that has more than one HTML
       
    21     element and hence implements value_from_datadict.
       
    22     """
       
    23     none_value = (0, '---')
       
    24     month_field = '%s_month'
       
    25     day_field = '%s_day'
       
    26     year_field = '%s_year'
       
    27 
       
    28     def __init__(self, attrs=None, years=None, required=True):
       
    29         # years is an optional list/tuple of years to use in the "year" select box.
       
    30         self.attrs = attrs or {}
       
    31         self.required = required
       
    32         if years:
       
    33             self.years = years
       
    34         else:
       
    35             this_year = datetime.date.today().year
       
    36             self.years = range(this_year, this_year+10)
       
    37 
       
    38     def render(self, name, value, attrs=None):
       
    39         try:
       
    40             year_val, month_val, day_val = value.year, value.month, value.day
       
    41         except AttributeError:
       
    42             year_val = month_val = day_val = None
       
    43             if isinstance(value, basestring):
       
    44                 match = RE_DATE.match(value)
       
    45                 if match:
       
    46                     year_val, month_val, day_val = [int(v) for v in match.groups()]
       
    47 
       
    48         output = []
       
    49 
       
    50         if 'id' in self.attrs:
       
    51             id_ = self.attrs['id']
       
    52         else:
       
    53             id_ = 'id_%s' % name
       
    54 
       
    55         month_choices = MONTHS.items()
       
    56         if not (self.required and value):
       
    57             month_choices.append(self.none_value)
       
    58         month_choices.sort()
       
    59         local_attrs = self.build_attrs(id=self.month_field % id_)
       
    60         s = Select(choices=month_choices)
       
    61         select_html = s.render(self.month_field % name, month_val, local_attrs)
       
    62         output.append(select_html)
       
    63 
       
    64         day_choices = [(i, i) for i in range(1, 32)]
       
    65         if not (self.required and value):
       
    66             day_choices.insert(0, self.none_value)
       
    67         local_attrs['id'] = self.day_field % id_
       
    68         s = Select(choices=day_choices)
       
    69         select_html = s.render(self.day_field % name, day_val, local_attrs)
       
    70         output.append(select_html)
       
    71 
       
    72         year_choices = [(i, i) for i in self.years]
       
    73         if not (self.required and value):
       
    74             year_choices.insert(0, self.none_value)
       
    75         local_attrs['id'] = self.year_field % id_
       
    76         s = Select(choices=year_choices)
       
    77         select_html = s.render(self.year_field % name, year_val, local_attrs)
       
    78         output.append(select_html)
       
    79 
       
    80         return mark_safe(u'\n'.join(output))
       
    81 
       
    82     def id_for_label(self, id_):
       
    83         return '%s_month' % id_
       
    84     id_for_label = classmethod(id_for_label)
       
    85 
       
    86     def value_from_datadict(self, data, files, name):
       
    87         y = data.get(self.year_field % name)
       
    88         m = data.get(self.month_field % name)
       
    89         d = data.get(self.day_field % name)
       
    90         if y == m == d == "0":
       
    91             return None
       
    92         if y and m and d:
       
    93             return '%s-%s-%s' % (y, m, d)
       
    94         return data.get(name, None)