Ticket #6231: ticket_6231_v4.patch

File ticket_6231_v4.patch, 25.1 KB (added by Bernd Schlapsi, 6 years ago)

New patch-version that works with current django-version (after Changeset [10585])

  • django/forms/extras/widgets.py

     
    66import re
    77
    88from django.forms.widgets import Widget, Select
    9 from django.utils.dates import MONTHS
     9from django.utils.dates import MONTHS, MONTHS_AP, MONTHS_3
    1010from django.utils.safestring import mark_safe
     11from django.conf import settings
    1112
    12 __all__ = ('SelectDateWidget',)
     13__all__ = ('SelectDateWidget', 'SelectTimeWidget',)
    1314
    1415RE_DATE = re.compile(r'(\d{4})-(\d\d?)-(\d\d?)$')
    1516
    16 class SelectDateWidget(Widget):
     17
     18class SelectDateWidgetBase(Widget):
    1719    """
     20    Base class for SelectDateWidget, SelectDateTimeWidget and
     21    SelectTimeWidget.
     22    """
     23    def __init__(self, attrs=None, format=None, required=True):
     24        if attrs is None:
     25            attrs = {}
     26        self.attrs = attrs
     27        self.values = {}
     28        self.format = self.parse_format(format)
     29        self.required = required
     30
     31    def render(self, name, value, attrs=None):
     32        """
     33        Return the html code of the widget.
     34        """
     35        if 'id' in self.attrs:
     36            id_ = self.attrs['id']
     37        else:
     38            id_ = 'id_%s' % name
     39        local_attrs = self.build_attrs()
     40        self.values = self.parse_value(value)
     41        output = []
     42        for (n, fmt) in self.format:
     43            select_name = '%s_%s' % (name, n)
     44            local_attrs['id'] = '%s_%s' % (id_, n)
     45            if hasattr(self, '%s_choices' % n):
     46                choices=getattr(self, '%s_choices' % n)(fmt)
     47                if not self.required or not self.values[n]:
     48                    choices.insert(0, (-1, '---'))
     49                select = Select(choices=choices)
     50                html = select.render(select_name, self.values[n], local_attrs)
     51                output.append(html)
     52        return mark_safe(u'\n'.join(output))
     53
     54    def id_for_label(self, id_):
     55        return '%s_%s' % (self.format[0][1], id_)
     56    id_for_label = classmethod(id_for_label)
     57
     58    def value_from_datadict(self, data, files, name):
     59        raise NotImplementedError('SelectDateWidgetBase::value_from_datadict()\
     60                is abstract and must be implemented in child classes')
     61
     62    def parse_format(self, fmt):
     63        raise NotImplementedError('SelectDateWidgetBase::parse_format() is \
     64                abstract and must be implemented in child classes')
     65
     66    def parse_value(self, fmt):
     67        raise NotImplementedError('SelectDateWidgetBase::parse_value() is \
     68                abstract and must be implemented in child classes')
     69
     70
     71class SelectDateWidget(SelectDateWidgetBase):
     72    """
    1873    A Widget that splits date input into three <select> boxes.
    1974
    2075    This also serves as an example of a Widget that has more than one HTML
    2176    element and hence implements value_from_datadict.
    2277    """
    23     none_value = (0, '---')
    24     month_field = '%s_month'
    25     day_field = '%s_day'
    26     year_field = '%s_year'
    2778
    28     def __init__(self, attrs=None, years=None, required=True):
     79    def __init__(self, attrs=None, years=None, format=None, required=True):
    2980        # years is an optional list/tuple of years to use in the "year" select box.
    30         self.attrs = attrs or {}
    31         self.required = required
    3281        if years:
    3382            self.years = years
    3483        else:
    3584            this_year = datetime.date.today().year
    3685            self.years = range(this_year, this_year+10)
     86        super(SelectDateWidget, self).__init__(attrs, format, required)
    3787
    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()]
     88    def value_from_datadict(self, data, files, name):
     89        vals = []
     90        y = data.get('%s_year' % name)
     91        m = data.get('%s_month' % name)
     92        d = data.get('%s_day' % name)
     93        if y == m == d == '-1':
     94            return None
     95        if y and m and d:
     96            return u'-'.join([y, m, d])
     97        return data.get(name, None)
    4798
    48         output = []
    49 
    50         if 'id' in self.attrs:
    51             id_ = self.attrs['id']
     99    def parse_value(self, val):
     100        ret = {}
     101        if isinstance(val, datetime.date):
     102            ret['month'] = val.month
     103            ret['day'] = val.day
     104            ret['year'] = val.year
    52105        else:
    53             id_ = 'id_%s' % name
     106            try:
     107                l = map(int, val.split('-'))
     108            except (ValueError, AttributeError):
     109                l = (None, None, None)
     110            for i, k in [(0, 'year'), (1, 'month'), (2, 'day')]:
     111                try:
     112                    ret[k] = l[i]
     113                except IndexError:
     114                    ret[k] = None
     115        return ret
    54116
    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)
     117    def parse_format(self, fmt):
     118        """
     119        Parse the given format `fmt` and set the format property.
     120        """
     121        if fmt is None:
     122            fmt = settings.DATE_FORMAT
     123        ret = []
     124        for item in fmt:
     125            if item in ['d', 'D', 'j', 'L']:
     126                ret.append(('day', item,))
     127            elif item in ['n', 'm', 'F', 'b', 'M', 'N']:
     128                ret.append(('month', item,))
     129            elif item in ['y', 'Y']:
     130                ret.append(('year', item,))
     131        return ret
    63132
    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)
     133    def month_choices(self, fmt):
     134        """
     135        Return list of choices (tuple (key, value)) for monthes select.
     136        """
     137        if fmt == 'n':
     138            # month numbers without leading 0 (1 .. 12)
     139            return [(i, i) for i in range(1, 13)]
     140        elif fmt == 'm':
     141            # month numbers with leading 0 (01 .. 12)
     142            return [(i, '%02d' % i) for i in range(1, 13)]
     143        elif fmt in ['F', 'b', 'M', 'N']:
     144            if fmt == 'F':
     145                # full month names
     146                month_choices = MONTHS.items()
     147            elif fmt == 'b':
     148                # 3 first letters of month lowercase
     149                month_choices = [(k, v.lower()) for (k, v) in MONTHS_3.items()]
     150            elif fmt == 'M':
     151                # 3 first letters of month
     152                month_choices = MONTHS_3.items()
     153            elif fmt == 'N':
     154                # abbrev of month names
     155                month_choices = MONTHS_AP.items()
     156            month_choices.sort()
     157            return month_choices
     158        return []
    71159
    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)
     160    def day_choices(self, fmt):
     161        """
     162        Return list of choices (tuple (key, value)) for days select.
     163        """
     164        if fmt == 'j':
     165            # day of month number without leading 0
     166            return [(i, i) for i in range(1, 32)]
     167        elif fmt == 'd':
     168            # day of month number with leading 0
     169            return [(i, '%02d' % i) for i in range(1, 32)]
     170        return []
    79171
    80         return mark_safe(u'\n'.join(output))
     172    def year_choices(self, fmt):
     173        """
     174        Return list of choices (tuple (key, value)) for years select.
     175        """
     176        if fmt == 'Y':
     177            # years with 4 numbers
     178            return [(i, i) for i in self.years]
     179        elif fmt == 'y':
     180            # years with only the last 2 numbers
     181            return [(i, str(i)[-2:]) for i in self.years]
     182        return []
    81183
    82     def id_for_label(self, id_):
    83         return '%s_month' % id_
    84     id_for_label = classmethod(id_for_label)
    85184
     185class SelectTimeWidget(SelectDateWidgetBase):
     186    """
     187    A Widget that splits time input into two or three <select> boxes.
     188    XXX: at the moment it is limited to theses formats: 'Hi' and 'His'.
     189    """
     190    def __init__(self, attrs=None, format=None, required=True):
     191        super(SelectTimeWidget, self).__init__(attrs, format, required)
     192
     193    def parse_format(self, fmt):
     194        if fmt not in ['Hi', 'His']:
     195            fmt = 'Hi'
     196        ret = []
     197        for item in fmt:
     198            if item == 'H':
     199                ret.append(('hour', item,))
     200            elif item == 'i':
     201                ret.append(('minute', item,))
     202            elif item == 's':
     203                ret.append(('second', item,))
     204        return ret
     205
     206    def parse_value(self, val):
     207        ret = {}
     208        if isinstance(val, datetime.time):
     209            ret['hour'] = val.hour
     210            ret['minute'] = val.minute
     211            ret['second'] = val.second
     212        else:
     213            try:
     214                l = map(int, val.split(':'))
     215            except (ValueError, AttributeError):
     216                l = (None, None, None)
     217            for i, k in [(0, 'hour'), (1, 'minute'), (2, 'second')]:
     218                try:
     219                    ret[k] = l[i]
     220                except IndexError:
     221                    ret[k] = None
     222        return ret
     223
    86224    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)
     225        vals = []
     226        h = data.get('%s_hour' % name)
     227        m = data.get('%s_minute' % name)
     228        s = data.get('%s_second' % name)
     229        if h and m:
     230            if s:
     231                return u':'.join([h, m, s])
     232            else:
     233                return u':'.join([h, m])
    94234        return data.get(name, None)
     235
     236    def hour_choices(self, fmt):
     237        """
     238        Return list of choices (tuple (key, value)) for hours select.
     239        """
     240        # hour 24H format with leading 0
     241        return [(i, '%02d' % i) for i in range(0, 24)]
     242
     243    def minute_choices(self, fmt):
     244        """
     245        Return list of choices (tuple (key, value)) for minutes select.
     246        """
     247        # minutes with leading 0
     248        return [(i, '%02d' % i) for i in range(0, 60)]
     249
     250    def second_choices(self, fmt):
     251        """
     252        Return list of choices (tuple (key, value)) for seconds select.
     253        """
     254        # seconds with leading 0
     255        return [(i, '%02d' % i) for i in range(0, 60)]
     256 No newline at end of file
  • tests/regressiontests/forms/extra.py

     
    2020# SelectDateWidget ############################################################
    2121
    2222>>> from django.forms.extras import SelectDateWidget
    23 >>> w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
     23>>> w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), format='FjY')
    2424>>> print w.render('mydate', '')
    2525<select name="mydate_month" id="id_mydate_month">
    26 <option value="0">---</option>
     26<option value="-1">---</option>
    2727<option value="1">January</option>
    2828<option value="2">February</option>
    2929<option value="3">March</option>
     
    3838<option value="12">December</option>
    3939</select>
    4040<select name="mydate_day" id="id_mydate_day">
    41 <option value="0">---</option>
     41<option value="-1">---</option>
    4242<option value="1">1</option>
    4343<option value="2">2</option>
    4444<option value="3">3</option>
     
    7272<option value="31">31</option>
    7373</select>
    7474<select name="mydate_year" id="id_mydate_year">
    75 <option value="0">---</option>
     75<option value="-1">---</option>
    7676<option value="2007">2007</option>
    7777<option value="2008">2008</option>
    7878<option value="2009">2009</option>
     
    219219>>> w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
    220220>>> print w.render('mydate', '')
    221221<select name="mydate_month" id="id_mydate_month">
    222 <option value="0">---</option>
    223 <option value="1">January</option>
    224 <option value="2">February</option>
     222<option value="-1">---</option>
     223<option value="1">Jan.</option>
     224<option value="2">Feb.</option>
    225225<option value="3">March</option>
    226226<option value="4">April</option>
    227227<option value="5">May</option>
    228228<option value="6">June</option>
    229229<option value="7">July</option>
    230 <option value="8">August</option>
    231 <option value="9">September</option>
    232 <option value="10">October</option>
    233 <option value="11">November</option>
    234 <option value="12">December</option>
     230<option value="8">Aug.</option>
     231<option value="9">Sept.</option>
     232<option value="10">Oct.</option>
     233<option value="11">Nov.</option>
     234<option value="12">Dec.</option>
    235235</select>
    236236<select name="mydate_day" id="id_mydate_day">
    237 <option value="0">---</option>
     237<option value="-1">---</option>
    238238<option value="1">1</option>
    239239<option value="2">2</option>
    240240<option value="3">3</option>
     
    268268<option value="31">31</option>
    269269</select>
    270270<select name="mydate_year" id="id_mydate_year">
    271 <option value="0">---</option>
     271<option value="-1">---</option>
    272272<option value="2007">2007</option>
    273273<option value="2008">2008</option>
    274274<option value="2009">2009</option>
     
    282282</select>
    283283>>> print w.render('mydate', '2010-04-15')
    284284<select name="mydate_month" id="id_mydate_month">
    285 <option value="0">---</option>
    286 <option value="1">January</option>
    287 <option value="2">February</option>
     285<option value="-1">---</option>
     286<option value="1">Jan.</option>
     287<option value="2">Feb.</option>
    288288<option value="3">March</option>
    289289<option value="4" selected="selected">April</option>
    290290<option value="5">May</option>
    291291<option value="6">June</option>
    292292<option value="7">July</option>
    293 <option value="8">August</option>
    294 <option value="9">September</option>
    295 <option value="10">October</option>
    296 <option value="11">November</option>
    297 <option value="12">December</option>
     293<option value="8">Aug.</option>
     294<option value="9">Sept.</option>
     295<option value="10">Oct.</option>
     296<option value="11">Nov.</option>
     297<option value="12">Dec.</option>
    298298</select>
    299299<select name="mydate_day" id="id_mydate_day">
    300 <option value="0">---</option>
     300<option value="-1">---</option>
    301301<option value="1">1</option>
    302302<option value="2">2</option>
    303303<option value="3">3</option>
     
    331331<option value="31">31</option>
    332332</select>
    333333<select name="mydate_year" id="id_mydate_year">
    334 <option value="0">---</option>
     334<option value="-1">---</option>
    335335<option value="2007">2007</option>
    336336<option value="2008">2008</option>
    337337<option value="2009">2009</option>
     
    3643642008-04-01
    365365
    366366
     367# SelectTimeWidget ############################################################
     368
     369>>> from django.forms.extras import SelectTimeWidget
     370>>> w = SelectTimeWidget()
     371>>> print w.render('mytime', '')
     372<select name="mytime_hour" id="id_mytime_hour">
     373<option value="-1">---</option>
     374<option value="0">00</option>
     375<option value="1">01</option>
     376<option value="2">02</option>
     377<option value="3">03</option>
     378<option value="4">04</option>
     379<option value="5">05</option>
     380<option value="6">06</option>
     381<option value="7">07</option>
     382<option value="8">08</option>
     383<option value="9">09</option>
     384<option value="10">10</option>
     385<option value="11">11</option>
     386<option value="12">12</option>
     387<option value="13">13</option>
     388<option value="14">14</option>
     389<option value="15">15</option>
     390<option value="16">16</option>
     391<option value="17">17</option>
     392<option value="18">18</option>
     393<option value="19">19</option>
     394<option value="20">20</option>
     395<option value="21">21</option>
     396<option value="22">22</option>
     397<option value="23">23</option>
     398</select>
     399<select name="mytime_minute" id="id_mytime_minute">
     400<option value="-1">---</option>
     401<option value="0">00</option>
     402<option value="1">01</option>
     403<option value="2">02</option>
     404<option value="3">03</option>
     405<option value="4">04</option>
     406<option value="5">05</option>
     407<option value="6">06</option>
     408<option value="7">07</option>
     409<option value="8">08</option>
     410<option value="9">09</option>
     411<option value="10">10</option>
     412<option value="11">11</option>
     413<option value="12">12</option>
     414<option value="13">13</option>
     415<option value="14">14</option>
     416<option value="15">15</option>
     417<option value="16">16</option>
     418<option value="17">17</option>
     419<option value="18">18</option>
     420<option value="19">19</option>
     421<option value="20">20</option>
     422<option value="21">21</option>
     423<option value="22">22</option>
     424<option value="23">23</option>
     425<option value="24">24</option>
     426<option value="25">25</option>
     427<option value="26">26</option>
     428<option value="27">27</option>
     429<option value="28">28</option>
     430<option value="29">29</option>
     431<option value="30">30</option>
     432<option value="31">31</option>
     433<option value="32">32</option>
     434<option value="33">33</option>
     435<option value="34">34</option>
     436<option value="35">35</option>
     437<option value="36">36</option>
     438<option value="37">37</option>
     439<option value="38">38</option>
     440<option value="39">39</option>
     441<option value="40">40</option>
     442<option value="41">41</option>
     443<option value="42">42</option>
     444<option value="43">43</option>
     445<option value="44">44</option>
     446<option value="45">45</option>
     447<option value="46">46</option>
     448<option value="47">47</option>
     449<option value="48">48</option>
     450<option value="49">49</option>
     451<option value="50">50</option>
     452<option value="51">51</option>
     453<option value="52">52</option>
     454<option value="53">53</option>
     455<option value="54">54</option>
     456<option value="55">55</option>
     457<option value="56">56</option>
     458<option value="57">57</option>
     459<option value="58">58</option>
     460<option value="59">59</option>
     461</select>
     462>>> w = SelectTimeWidget(required=False)
     463>>> print w.render('mytime', '15:45')
     464<select name="mytime_hour" id="id_mytime_hour">
     465<option value="-1">---</option>
     466<option value="0">00</option>
     467<option value="1">01</option>
     468<option value="2">02</option>
     469<option value="3">03</option>
     470<option value="4">04</option>
     471<option value="5">05</option>
     472<option value="6">06</option>
     473<option value="7">07</option>
     474<option value="8">08</option>
     475<option value="9">09</option>
     476<option value="10">10</option>
     477<option value="11">11</option>
     478<option value="12">12</option>
     479<option value="13">13</option>
     480<option value="14">14</option>
     481<option value="15" selected="selected">15</option>
     482<option value="16">16</option>
     483<option value="17">17</option>
     484<option value="18">18</option>
     485<option value="19">19</option>
     486<option value="20">20</option>
     487<option value="21">21</option>
     488<option value="22">22</option>
     489<option value="23">23</option>
     490</select>
     491<select name="mytime_minute" id="id_mytime_minute">
     492<option value="-1">---</option>
     493<option value="0">00</option>
     494<option value="1">01</option>
     495<option value="2">02</option>
     496<option value="3">03</option>
     497<option value="4">04</option>
     498<option value="5">05</option>
     499<option value="6">06</option>
     500<option value="7">07</option>
     501<option value="8">08</option>
     502<option value="9">09</option>
     503<option value="10">10</option>
     504<option value="11">11</option>
     505<option value="12">12</option>
     506<option value="13">13</option>
     507<option value="14">14</option>
     508<option value="15">15</option>
     509<option value="16">16</option>
     510<option value="17">17</option>
     511<option value="18">18</option>
     512<option value="19">19</option>
     513<option value="20">20</option>
     514<option value="21">21</option>
     515<option value="22">22</option>
     516<option value="23">23</option>
     517<option value="24">24</option>
     518<option value="25">25</option>
     519<option value="26">26</option>
     520<option value="27">27</option>
     521<option value="28">28</option>
     522<option value="29">29</option>
     523<option value="30">30</option>
     524<option value="31">31</option>
     525<option value="32">32</option>
     526<option value="33">33</option>
     527<option value="34">34</option>
     528<option value="35">35</option>
     529<option value="36">36</option>
     530<option value="37">37</option>
     531<option value="38">38</option>
     532<option value="39">39</option>
     533<option value="40">40</option>
     534<option value="41">41</option>
     535<option value="42">42</option>
     536<option value="43">43</option>
     537<option value="44">44</option>
     538<option value="45" selected="selected">45</option>
     539<option value="46">46</option>
     540<option value="47">47</option>
     541<option value="48">48</option>
     542<option value="49">49</option>
     543<option value="50">50</option>
     544<option value="51">51</option>
     545<option value="52">52</option>
     546<option value="53">53</option>
     547<option value="54">54</option>
     548<option value="55">55</option>
     549<option value="56">56</option>
     550<option value="57">57</option>
     551<option value="58">58</option>
     552<option value="59">59</option>
     553</select>
     554>>> w = SelectTimeWidget(required=True)
     555>>> print w.render('mytime', '15:45')
     556<select name="mytime_hour" id="id_mytime_hour">
     557<option value="0">00</option>
     558<option value="1">01</option>
     559<option value="2">02</option>
     560<option value="3">03</option>
     561<option value="4">04</option>
     562<option value="5">05</option>
     563<option value="6">06</option>
     564<option value="7">07</option>
     565<option value="8">08</option>
     566<option value="9">09</option>
     567<option value="10">10</option>
     568<option value="11">11</option>
     569<option value="12">12</option>
     570<option value="13">13</option>
     571<option value="14">14</option>
     572<option value="15" selected="selected">15</option>
     573<option value="16">16</option>
     574<option value="17">17</option>
     575<option value="18">18</option>
     576<option value="19">19</option>
     577<option value="20">20</option>
     578<option value="21">21</option>
     579<option value="22">22</option>
     580<option value="23">23</option>
     581</select>
     582<select name="mytime_minute" id="id_mytime_minute">
     583<option value="0">00</option>
     584<option value="1">01</option>
     585<option value="2">02</option>
     586<option value="3">03</option>
     587<option value="4">04</option>
     588<option value="5">05</option>
     589<option value="6">06</option>
     590<option value="7">07</option>
     591<option value="8">08</option>
     592<option value="9">09</option>
     593<option value="10">10</option>
     594<option value="11">11</option>
     595<option value="12">12</option>
     596<option value="13">13</option>
     597<option value="14">14</option>
     598<option value="15">15</option>
     599<option value="16">16</option>
     600<option value="17">17</option>
     601<option value="18">18</option>
     602<option value="19">19</option>
     603<option value="20">20</option>
     604<option value="21">21</option>
     605<option value="22">22</option>
     606<option value="23">23</option>
     607<option value="24">24</option>
     608<option value="25">25</option>
     609<option value="26">26</option>
     610<option value="27">27</option>
     611<option value="28">28</option>
     612<option value="29">29</option>
     613<option value="30">30</option>
     614<option value="31">31</option>
     615<option value="32">32</option>
     616<option value="33">33</option>
     617<option value="34">34</option>
     618<option value="35">35</option>
     619<option value="36">36</option>
     620<option value="37">37</option>
     621<option value="38">38</option>
     622<option value="39">39</option>
     623<option value="40">40</option>
     624<option value="41">41</option>
     625<option value="42">42</option>
     626<option value="43">43</option>
     627<option value="44">44</option>
     628<option value="45" selected="selected">45</option>
     629<option value="46">46</option>
     630<option value="47">47</option>
     631<option value="48">48</option>
     632<option value="49">49</option>
     633<option value="50">50</option>
     634<option value="51">51</option>
     635<option value="52">52</option>
     636<option value="53">53</option>
     637<option value="54">54</option>
     638<option value="55">55</option>
     639<option value="56">56</option>
     640<option value="57">57</option>
     641<option value="58">58</option>
     642<option value="59">59</option>
     643</select>
     644
     645Accepts a datetime or a string:
     646
     647>>> w.render('mydate', datetime.time(15, 45, 15)) == w.render('mydate', '15:45:15')
     648True
     649
     650Using a SelectDateWidget in a form:
     651
     652>>> class GetTime(Form):
     653...     mytime = TimeField(widget=SelectTimeWidget)
     654>>> a = GetTime({'mytime_hour':'15', 'mytime_minute':'45', 'mytime_second':'15'})
     655>>> print a.is_valid()
     656True
     657>>> print a.cleaned_data['mytime']
     65815:45:15
     659
     660As with any widget that implements get_value_from_datadict,
     661we must be prepared to accept the input from the "as_hidden"
     662rendering as well.
     663
     664>>> print a['mytime'].as_hidden()
     665<input type="hidden" name="mytime" value="15:45:15" id="id_mytime" />
     666>>> b=GetTime({'mytime':'15:45:15'})
     667>>> print b.is_valid()
     668True
     669>>> print b.cleaned_data['mytime']
     67015:45:15
     671
     672
    367673# MultiWidget and MultiValueField #############################################
    368674# MultiWidgets are widgets composed of other widgets. They are usually
    369675# combined with MultiValueFields - a field that is composed of other fields.
Back to Top