Fixed #20986 -- Enabled SelectDateWidget to use custom months
Reviewed by Trac alias MarkusH.
This commit is contained in:
parent
b89c2a5d9e
commit
da800be6dd
|
@ -51,16 +51,23 @@ class SelectDateWidget(Widget):
|
||||||
day_field = '%s_day'
|
day_field = '%s_day'
|
||||||
year_field = '%s_year'
|
year_field = '%s_year'
|
||||||
|
|
||||||
def __init__(self, attrs=None, years=None, required=True):
|
def __init__(self, attrs=None, years=None, required=True, months=None):
|
||||||
# years is an optional list/tuple of years to use in the "year" select box.
|
|
||||||
self.attrs = attrs or {}
|
self.attrs = attrs or {}
|
||||||
self.required = required
|
self.required = required
|
||||||
|
|
||||||
|
# Optional list or tuple of years to use in the "year" select box.
|
||||||
if years:
|
if years:
|
||||||
self.years = years
|
self.years = years
|
||||||
else:
|
else:
|
||||||
this_year = datetime.date.today().year
|
this_year = datetime.date.today().year
|
||||||
self.years = range(this_year, this_year+10)
|
self.years = range(this_year, this_year+10)
|
||||||
|
|
||||||
|
# Optional dict of months to use in the "month" select box.
|
||||||
|
if months:
|
||||||
|
self.months = months
|
||||||
|
else:
|
||||||
|
self.months = MONTHS
|
||||||
|
|
||||||
def render(self, name, value, attrs=None):
|
def render(self, name, value, attrs=None):
|
||||||
try:
|
try:
|
||||||
year_val, month_val, day_val = value.year, value.month, value.day
|
year_val, month_val, day_val = value.year, value.month, value.day
|
||||||
|
@ -80,7 +87,7 @@ class SelectDateWidget(Widget):
|
||||||
year_val, month_val, day_val = [int(v) for v in match.groups()]
|
year_val, month_val, day_val = [int(v) for v in match.groups()]
|
||||||
choices = [(i, i) for i in self.years]
|
choices = [(i, i) for i in self.years]
|
||||||
year_html = self.create_select(name, self.year_field, value, year_val, choices)
|
year_html = self.create_select(name, self.year_field, value, year_val, choices)
|
||||||
choices = list(six.iteritems(MONTHS))
|
choices = list(six.iteritems(self.months))
|
||||||
month_html = self.create_select(name, self.month_field, value, month_val, choices)
|
month_html = self.create_select(name, self.month_field, value, month_val, choices)
|
||||||
choices = [(i, i) for i in range(1, 32)]
|
choices = [(i, i) for i in range(1, 32)]
|
||||||
day_html = self.create_select(name, self.day_field, value, day_val, choices)
|
day_html = self.create_select(name, self.day_field, value, day_val, choices)
|
||||||
|
|
|
@ -763,3 +763,20 @@ Composite widgets
|
||||||
|
|
||||||
An optional list/tuple of years to use in the "year" select box.
|
An optional list/tuple of years to use in the "year" select box.
|
||||||
The default is a list containing the current year and the next 9 years.
|
The default is a list containing the current year and the next 9 years.
|
||||||
|
|
||||||
|
.. attribute:: SelectDateWidget.months
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
|
||||||
|
An optional dict of months to use in the "months" select box.
|
||||||
|
|
||||||
|
The keys of the dict correspond to the month number (1-indexed) and
|
||||||
|
the values are the displayed months.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
MONTHS = {
|
||||||
|
1:_('jan'), 2:_('feb'), 3:_('mar'), 4:_('apr'),
|
||||||
|
5:_('may'), 6:_('jun'), 7:_('jul'), 8:_('aug'),
|
||||||
|
9:_('sep'), 10:_('oct'), 11:_('nov'), 12:_('dec')
|
||||||
|
}
|
||||||
|
|
|
@ -213,6 +213,10 @@ Forms
|
||||||
return ``self.cleaned_data``. If it does return a changed dictionary then
|
return ``self.cleaned_data``. If it does return a changed dictionary then
|
||||||
that will still be used.
|
that will still be used.
|
||||||
|
|
||||||
|
* :attr:`SelectDateWidget.months
|
||||||
|
<django.forms.extras.widgets.SelectDateWidget.months>` can be used to
|
||||||
|
customize the wording of the months displayed in the select widget.
|
||||||
|
|
||||||
Management Commands
|
Management Commands
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ from django.test import TestCase
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
from django.utils.dates import MONTHS_AP
|
||||||
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
|
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
|
||||||
|
|
||||||
from .test_error_messages import AssertFormErrorsMixin
|
from .test_error_messages import AssertFormErrorsMixin
|
||||||
|
@ -32,6 +33,8 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
|
||||||
# The forms library comes with some extra, higher-level Field and Widget
|
# The forms library comes with some extra, higher-level Field and Widget
|
||||||
def test_selectdate(self):
|
def test_selectdate(self):
|
||||||
w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
|
w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'))
|
||||||
|
|
||||||
|
# Rendering the default state.
|
||||||
self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
|
self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
|
||||||
<option value="0">---</option>
|
<option value="0">---</option>
|
||||||
<option value="1">January</option>
|
<option value="1">January</option>
|
||||||
|
@ -96,8 +99,11 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
|
||||||
<option value="2015">2015</option>
|
<option value="2015">2015</option>
|
||||||
<option value="2016">2016</option>
|
<option value="2016">2016</option>
|
||||||
</select>""")
|
</select>""")
|
||||||
|
|
||||||
|
# Rendering the None or '' values should yield the same output.
|
||||||
self.assertHTMLEqual(w.render('mydate', None), w.render('mydate', ''))
|
self.assertHTMLEqual(w.render('mydate', None), w.render('mydate', ''))
|
||||||
|
|
||||||
|
# Rendering a string value.
|
||||||
self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
|
self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """<select name="mydate_month" id="id_mydate_month">
|
||||||
<option value="1">January</option>
|
<option value="1">January</option>
|
||||||
<option value="2">February</option>
|
<option value="2">February</option>
|
||||||
|
@ -158,10 +164,10 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
|
||||||
<option value="2016">2016</option>
|
<option value="2016">2016</option>
|
||||||
</select>""")
|
</select>""")
|
||||||
|
|
||||||
# Accepts a datetime or a string:
|
# Rendering a datetime value.
|
||||||
self.assertHTMLEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15'))
|
self.assertHTMLEqual(w.render('mydate', datetime.date(2010, 4, 15)), w.render('mydate', '2010-04-15'))
|
||||||
|
|
||||||
# Invalid dates still render the failed date:
|
# Invalid dates should still render the failed date.
|
||||||
self.assertHTMLEqual(w.render('mydate', '2010-02-31'), """<select name="mydate_month" id="id_mydate_month">
|
self.assertHTMLEqual(w.render('mydate', '2010-02-31'), """<select name="mydate_month" id="id_mydate_month">
|
||||||
<option value="1">January</option>
|
<option value="1">January</option>
|
||||||
<option value="2" selected="selected">February</option>
|
<option value="2" selected="selected">February</option>
|
||||||
|
@ -222,7 +228,65 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
|
||||||
<option value="2016">2016</option>
|
<option value="2016">2016</option>
|
||||||
</select>""")
|
</select>""")
|
||||||
|
|
||||||
# Using a SelectDateWidget in a form:
|
# Rendering with a custom months dict.
|
||||||
|
w = SelectDateWidget(months=MONTHS_AP, years=('2013',))
|
||||||
|
self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
|
||||||
|
<option value="0">---</option>
|
||||||
|
<option value="1">Jan.</option>
|
||||||
|
<option value="2">Feb.</option>
|
||||||
|
<option value="3">March</option>
|
||||||
|
<option value="4">April</option>
|
||||||
|
<option value="5">May</option>
|
||||||
|
<option value="6">June</option>
|
||||||
|
<option value="7">July</option>
|
||||||
|
<option value="8">Aug.</option>
|
||||||
|
<option value="9">Sept.</option>
|
||||||
|
<option value="10">Oct.</option>
|
||||||
|
<option value="11">Nov.</option>
|
||||||
|
<option value="12">Dec.</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select name="mydate_day" id="id_mydate_day">
|
||||||
|
<option value="0">---</option>
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="2">2</option>
|
||||||
|
<option value="3">3</option>
|
||||||
|
<option value="4">4</option>
|
||||||
|
<option value="5">5</option>
|
||||||
|
<option value="6">6</option>
|
||||||
|
<option value="7">7</option>
|
||||||
|
<option value="8">8</option>
|
||||||
|
<option value="9">9</option>
|
||||||
|
<option value="10">10</option>
|
||||||
|
<option value="11">11</option>
|
||||||
|
<option value="12">12</option>
|
||||||
|
<option value="13">13</option>
|
||||||
|
<option value="14">14</option>
|
||||||
|
<option value="15">15</option>
|
||||||
|
<option value="16">16</option>
|
||||||
|
<option value="17">17</option>
|
||||||
|
<option value="18">18</option>
|
||||||
|
<option value="19">19</option>
|
||||||
|
<option value="20">20</option>
|
||||||
|
<option value="21">21</option>
|
||||||
|
<option value="22">22</option>
|
||||||
|
<option value="23">23</option>
|
||||||
|
<option value="24">24</option>
|
||||||
|
<option value="25">25</option>
|
||||||
|
<option value="26">26</option>
|
||||||
|
<option value="27">27</option>
|
||||||
|
<option value="28">28</option>
|
||||||
|
<option value="29">29</option>
|
||||||
|
<option value="30">30</option>
|
||||||
|
<option value="31">31</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select name="mydate_year" id="id_mydate_year">
|
||||||
|
<option value="0">---</option>
|
||||||
|
<option value="2013">2013</option>
|
||||||
|
</select>""")
|
||||||
|
|
||||||
|
# Using a SelectDateWidget in a form.
|
||||||
w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
|
w = SelectDateWidget(years=('2007','2008','2009','2010','2011','2012','2013','2014','2015','2016'), required=False)
|
||||||
self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
|
self.assertHTMLEqual(w.render('mydate', ''), """<select name="mydate_month" id="id_mydate_month">
|
||||||
<option value="0">---</option>
|
<option value="0">---</option>
|
||||||
|
|
Loading…
Reference in New Issue