Code

Ticket #5917: 5917.diff

File 5917.diff, 3.6 KB (added by SmileyChris, 6 years ago)

Allow widget to receive a datetime and also render invalid dates (validation doesn't belong in the widget)

Line 
1Index: django/newforms/extras/widgets.py
2===================================================================
3--- django/newforms/extras/widgets.py   (revision 7141)
4+++ django/newforms/extras/widgets.py   (working copy)
5@@ -3,6 +3,7 @@
6 """
7 
8 import datetime
9+import re
10 
11 from django.newforms.widgets import Widget, Select
12 from django.utils.dates import MONTHS
13@@ -10,6 +11,8 @@
14 
15 __all__ = ('SelectDateWidget',)
16 
17+RE_DATE = re.compile(r'(\d{4})-(\d\d?)-(\d\d?)$')
18+
19 class SelectDateWidget(Widget):
20     """
21     A Widget that splits date input into three <select> boxes.
22@@ -32,10 +35,13 @@
23 
24     def render(self, name, value, attrs=None):
25         try:
26-            value = datetime.date(*map(int, value.split('-')))
27             year_val, month_val, day_val = value.year, value.month, value.day
28-        except (AttributeError, TypeError, ValueError):
29+        except AttributeError:
30             year_val = month_val = day_val = None
31+            if isinstance(value, basestring):
32+                match = RE_DATE.match(value)
33+                if match:
34+                    year_val, month_val, day_val = [int(v) for v in match.groups()]
35 
36         output = []
37 
38Index: tests/regressiontests/forms/extra.py
39===================================================================
40--- tests/regressiontests/forms/extra.py        (revision 7141)
41+++ tests/regressiontests/forms/extra.py        (working copy)
42@@ -144,6 +144,73 @@
43 <option value="2016">2016</option>
44 </select>
45 
46+Accepts a datetime or a string:
47+
48+>>> w.render('mydate', datetime.date(2010, 4, 15)) == w.render('mydate', '2010-04-15')
49+True
50+
51+Invalid dates still render the failed date:
52+>>> print w.render('mydate', '2010-02-31')
53+<select name="mydate_month">
54+<option value="1">January</option>
55+<option value="2" selected="selected">February</option>
56+<option value="3">March</option>
57+<option value="4">April</option>
58+<option value="5">May</option>
59+<option value="6">June</option>
60+<option value="7">July</option>
61+<option value="8">August</option>
62+<option value="9">September</option>
63+<option value="10">October</option>
64+<option value="11">November</option>
65+<option value="12">December</option>
66+</select>
67+<select name="mydate_day">
68+<option value="1">1</option>
69+<option value="2">2</option>
70+<option value="3">3</option>
71+<option value="4">4</option>
72+<option value="5">5</option>
73+<option value="6">6</option>
74+<option value="7">7</option>
75+<option value="8">8</option>
76+<option value="9">9</option>
77+<option value="10">10</option>
78+<option value="11">11</option>
79+<option value="12">12</option>
80+<option value="13">13</option>
81+<option value="14">14</option>
82+<option value="15">15</option>
83+<option value="16">16</option>
84+<option value="17">17</option>
85+<option value="18">18</option>
86+<option value="19">19</option>
87+<option value="20">20</option>
88+<option value="21">21</option>
89+<option value="22">22</option>
90+<option value="23">23</option>
91+<option value="24">24</option>
92+<option value="25">25</option>
93+<option value="26">26</option>
94+<option value="27">27</option>
95+<option value="28">28</option>
96+<option value="29">29</option>
97+<option value="30">30</option>
98+<option value="31" selected="selected">31</option>
99+</select>
100+<select name="mydate_year">
101+<option value="2007">2007</option>
102+<option value="2008">2008</option>
103+<option value="2009">2009</option>
104+<option value="2010" selected="selected">2010</option>
105+<option value="2011">2011</option>
106+<option value="2012">2012</option>
107+<option value="2013">2013</option>
108+<option value="2014">2014</option>
109+<option value="2015">2015</option>
110+<option value="2016">2016</option>
111+</select>
112+
113 Using a SelectDateWidget in a form:
114 
115 >>> class GetDate(Form):