Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #20986 -- Enabled SelectDateWidget to use custom months

Reviewed by Trac alias MarkusH.
  • Loading branch information...
commit da800be6ddfdd4c88b48011ef264ea1ec6365725 1 parent b89c2a5
Loic Bistuer authored August 28, 2013 akaariai committed August 28, 2013
13  django/forms/extras/widgets.py
@@ -51,16 +51,23 @@ class SelectDateWidget(Widget):
51 51
     day_field = '%s_day'
52 52
     year_field = '%s_year'
53 53
 
54  
-    def __init__(self, attrs=None, years=None, required=True):
55  
-        # years is an optional list/tuple of years to use in the "year" select box.
  54
+    def __init__(self, attrs=None, years=None, required=True, months=None):
56 55
         self.attrs = attrs or {}
57 56
         self.required = required
  57
+
  58
+        # Optional list or tuple of years to use in the "year" select box.
58 59
         if years:
59 60
             self.years = years
60 61
         else:
61 62
             this_year = datetime.date.today().year
62 63
             self.years = range(this_year, this_year+10)
63 64
 
  65
+        # Optional dict of months to use in the "month" select box.
  66
+        if months:
  67
+            self.months = months
  68
+        else:
  69
+            self.months = MONTHS
  70
+
64 71
     def render(self, name, value, attrs=None):
65 72
         try:
66 73
             year_val, month_val, day_val = value.year, value.month, value.day
@@ -80,7 +87,7 @@ def render(self, name, value, attrs=None):
80 87
                         year_val, month_val, day_val = [int(v) for v in match.groups()]
81 88
         choices = [(i, i) for i in self.years]
82 89
         year_html = self.create_select(name, self.year_field, value, year_val, choices)
83  
-        choices = list(six.iteritems(MONTHS))
  90
+        choices = list(six.iteritems(self.months))
84 91
         month_html = self.create_select(name, self.month_field, value, month_val, choices)
85 92
         choices = [(i, i) for i in range(1, 32)]
86 93
         day_html = self.create_select(name, self.day_field, value, day_val,  choices)
17  docs/ref/forms/widgets.txt
@@ -763,3 +763,20 @@ Composite widgets
763 763
 
764 764
         An optional list/tuple of years to use in the "year" select box.
765 765
         The default is a list containing the current year and the next 9 years.
  766
+
  767
+    .. attribute:: SelectDateWidget.months
  768
+
  769
+        .. versionadded:: 1.7
  770
+
  771
+        An optional dict of months to use in the "months" select box.
  772
+
  773
+        The keys of the dict correspond to the month number (1-indexed) and
  774
+        the values are the displayed months.
  775
+
  776
+        .. code-block:: python
  777
+
  778
+            MONTHS = {
  779
+                1:_('jan'), 2:_('feb'), 3:_('mar'), 4:_('apr'),
  780
+                5:_('may'), 6:_('jun'), 7:_('jul'), 8:_('aug'),
  781
+                9:_('sep'), 10:_('oct'), 11:_('nov'), 12:_('dec')
  782
+            }
4  docs/releases/1.7.txt
@@ -213,6 +213,10 @@ Forms
213 213
   return ``self.cleaned_data``. If it does return a changed dictionary then
214 214
   that will still be used.
215 215
 
  216
+* :attr:`SelectDateWidget.months
  217
+  <django.forms.extras.widgets.SelectDateWidget.months>` can be used to
  218
+  customize the wording of the months displayed in the select widget.
  219
+
216 220
 Management Commands
217 221
 ^^^^^^^^^^^^^^^^^^^
218 222
 
70  tests/forms_tests/tests/test_extra.py
@@ -10,6 +10,7 @@
10 10
 from django.test.utils import override_settings
11 11
 from django.utils import six
12 12
 from django.utils import translation
  13
+from django.utils.dates import MONTHS_AP
13 14
 from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
14 15
 
15 16
 from .test_error_messages import AssertFormErrorsMixin
@@ -32,6 +33,8 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
32 33
     # The forms library comes with some extra, higher-level Field and Widget
33 34
     def test_selectdate(self):
34 35
         w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
  36
+
  37
+        # Rendering the default state.
35 38
         self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
36 39
 <option value="0">---</option>
37 40
 <option value="1">January</option>
@@ -96,8 +99,11 @@ def test_selectdate(self):
96 99
 <option value="2015">2015</option>
97 100
 <option value="2016">2016</option>
98 101
 </select>""")
  102
+
  103
+        # Rendering the None or '' values should yield the same output.
99 104
         self.assertHTMLEqual(w.render('mydate', None), w.render('mydate', ''))
100 105
 
  106
+        # Rendering a string value.
101 107
         self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
102 108
 <option value="1">January</option>
103 109
 <option value="2">February</option>
@@ -158,10 +164,10 @@ def test_selectdate(self):
158 164
 <option value="2016">2016</option>
159 165
 </select>""")
160 166
 
161  
-        # Accepts a datetime or a string:
  167
+        # Rendering a datetime value.
162 168
         self.assertHTMLEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15'))
163 169
 
164  
-        # Invalid dates still render the failed date:
  170
+        # Invalid dates should still render the failed date.
165 171
         self.assertHTMLEqual(w.render('mydate', '2010-02-31'), """<select name="mydate_month" id="id_mydate_month">
166 172
 <option value="1">January</option>
167 173
 <option value="2" selected="selected">February</option>
@@ -222,7 +228,65 @@ def test_selectdate(self):
222 228
 <option value="2016">2016</option>
223 229
 </select>""")
224 230
 
225  
-        # Using a SelectDateWidget in a form:
  231
+        # Rendering with a custom months dict.
  232
+        w = SelectDateWidget(months=MONTHS_AP, years=('2013',))
  233
+        self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
  234
+<option value="0">---</option>
  235
+<option value="1">Jan.</option>
  236
+<option value="2">Feb.</option>
  237
+<option value="3">March</option>
  238
+<option value="4">April</option>
  239
+<option value="5">May</option>
  240
+<option value="6">June</option>
  241
+<option value="7">July</option>
  242
+<option value="8">Aug.</option>
  243
+<option value="9">Sept.</option>
  244
+<option value="10">Oct.</option>
  245
+<option value="11">Nov.</option>
  246
+<option value="12">Dec.</option>
  247
+</select>
  248
+
  249
+<select name="mydate_day" id="id_mydate_day">
  250
+<option value="0">---</option>
  251
+<option value="1">1</option>
  252
+<option value="2">2</option>
  253
+<option value="3">3</option>
  254
+<option value="4">4</option>
  255
+<option value="5">5</option>
  256
+<option value="6">6</option>
  257
+<option value="7">7</option>
  258
+<option value="8">8</option>
  259
+<option value="9">9</option>
  260
+<option value="10">10</option>
  261
+<option value="11">11</option>
  262
+<option value="12">12</option>
  263
+<option value="13">13</option>
  264
+<option value="14">14</option>
  265
+<option value="15">15</option>
  266
+<option value="16">16</option>
  267
+<option value="17">17</option>
  268
+<option value="18">18</option>
  269
+<option value="19">19</option>
  270
+<option value="20">20</option>
  271
+<option value="21">21</option>
  272
+<option value="22">22</option>
  273
+<option value="23">23</option>
  274
+<option value="24">24</option>
  275
+<option value="25">25</option>
  276
+<option value="26">26</option>
  277
+<option value="27">27</option>
  278
+<option value="28">28</option>
  279
+<option value="29">29</option>
  280
+<option value="30">30</option>
  281
+<option value="31">31</option>
  282
+</select>
  283
+
  284
+<select name="mydate_year" id="id_mydate_year">
  285
+<option value="0">---</option>
  286
+<option value="2013">2013</option>
  287
+</select>""")
  288
+
  289
+        # Using a SelectDateWidget in a form.
226 290
         w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
227 291
         self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
228 292
 <option value="0">---</option>

0 notes on commit da800be

Please sign in to comment.
Something went wrong with that request. Please try again.