diff --git a/django/forms/extras/widgets.py b/django/forms/extras/widgets.py
index 7fd209f397..966ddd966c 100644
--- a/django/forms/extras/widgets.py
+++ b/django/forms/extras/widgets.py
@@ -53,9 +53,8 @@ class SelectDateWidget(Widget):
day_field = '%s_day'
year_field = '%s_year'
- def __init__(self, attrs=None, years=None, required=True, months=None):
+ def __init__(self, attrs=None, years=None, months=None):
self.attrs = attrs or {}
- self.required = required
# Optional list or tuple of years to use in the "year" select box.
if years:
@@ -139,7 +138,7 @@ class SelectDateWidget(Widget):
id_ = self.attrs['id']
else:
id_ = 'id_%s' % name
- if not (self.required and val):
+ if not self.is_required:
choices.insert(0, self.none_value)
local_attrs = self.build_attrs(id=field % id_)
s = Select(choices=choices)
diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt
index 9501da7ca1..e32e60be35 100644
--- a/docs/releases/1.7.txt
+++ b/docs/releases/1.7.txt
@@ -613,6 +613,11 @@ Miscellaneous
you relied on the default field ordering while having fields defined on both
the current class *and* on a parent ``Form``.
+* The ``required`` argument of
+ :class:`~django.forms.extras.widgets.SelectDateWidget` has been removed.
+ This widget now respects the form field's ``is_required`` attribute like
+ other widgets.
+
* :meth:`~django.db.models.query.QuerySet.select_related` now chains in the
same way as other similar calls like ``prefetch_related``. That is,
``select_related('foo', 'bar')`` is equivalent to
diff --git a/tests/forms_tests/tests/test_extra.py b/tests/forms_tests/tests/test_extra.py
index 4585a4e6ef..7988b52da4 100644
--- a/tests/forms_tests/tests/test_extra.py
+++ b/tests/forms_tests/tests/test_extra.py
@@ -26,10 +26,6 @@ class GetDate(Form):
mydate = DateField(widget=SelectDateWidget)
-class GetNotRequiredDate(Form):
- mydate = DateField(widget=SelectDateWidget, required=False)
-
-
class GetDateShowHiddenInitial(Form):
mydate = DateField(widget=SelectDateWidget, show_hidden_initial=True)
@@ -41,6 +37,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
# The forms library comes with some extra, higher-level Field and Widget
def test_selectdate(self):
+ self.maxDiff = None
w = SelectDateWidget(years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016'))
# Rendering the default state.
@@ -114,6 +111,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
# Rendering a string value.
self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """
+---
January
February
March
@@ -128,6 +126,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
December
+---
1
2
3
@@ -161,6 +160,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
31
+---
2007
2008
2009
@@ -178,6 +178,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
# Invalid dates should still render the failed date.
self.assertHTMLEqual(w.render('mydate', '2010-02-31'), """
+---
January
February
March
@@ -192,6 +193,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
December
+---
1
2
3
@@ -225,6 +227,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
31
+---
2007
2008
2009
@@ -293,133 +296,6 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
---
2013
- """)
-
- # Using a SelectDateWidget in a form.
- w = SelectDateWidget(years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016'), required=False)
- self.assertHTMLEqual(w.render('mydate', ''), """
----
-January
-February
-March
-April
-May
-June
-July
-August
-September
-October
-November
-December
-
-
----
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-
-
----
-2007
-2008
-2009
-2010
-2011
-2012
-2013
-2014
-2015
-2016
- """)
- self.assertHTMLEqual(w.render('mydate', '2010-04-15'), """
----
-January
-February
-March
-April
-May
-June
-July
-August
-September
-October
-November
-December
-
-
----
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-
-
----
-2007
-2008
-2009
-2010
-2011
-2012
-2013
-2014
-2015
-2016
""")
a = GetDate({'mydate_month': '4', 'mydate_day': '1', 'mydate_year': '2008'})
@@ -768,13 +644,15 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
self.assertTrue(FormWithFile().is_multipart())
self.assertTrue(FormWithImage().is_multipart())
- def test_field_not_required(self):
- b = GetNotRequiredDate({
- 'mydate_year': '',
- 'mydate_month': '',
- 'mydate_day': ''
- })
- self.assertFalse(b.has_changed())
+ def test_selectdatewidget_required(self):
+ class GetNotRequiredDate(Form):
+ mydate = DateField(widget=SelectDateWidget, required=False)
+
+ class GetRequiredDate(Form):
+ mydate = DateField(widget=SelectDateWidget, required=True)
+
+ self.assertFalse(GetNotRequiredDate().fields['mydate'].widget.is_required)
+ self.assertTrue(GetRequiredDate().fields['mydate'].widget.is_required)
@override_settings(USE_L10N=True)
@@ -788,7 +666,7 @@ class FormsExtraL10NTestCase(TestCase):
super(FormsExtraL10NTestCase, self).tearDown()
def test_l10n(self):
- 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'))
self.assertEqual(w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date'), '13-08-2010')
self.assertHTMLEqual(w.render('date', '13-08-2010'), """
diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
index 32eadfbb46..30e30407e4 100644
--- a/tests/i18n/tests.py
+++ b/tests/i18n/tests.py
@@ -415,6 +415,7 @@ class FormattingTests(TransRealMixin, TestCase):
but not formats
"""
with translation.override('ca', deactivate=True):
+ self.maxDiff = 3000
self.assertEqual('N j, Y', get_format('DATE_FORMAT'))
self.assertEqual(0, get_format('FIRST_DAY_OF_WEEK'))
self.assertEqual('.', get_format('DECIMAL_SEPARATOR'))
@@ -461,7 +462,7 @@ class FormattingTests(TransRealMixin, TestCase):
self.assertEqual(True, form2.is_valid())
self.assertEqual(datetime.date(2009, 12, 31), form2.cleaned_data['date_field'])
self.assertHTMLEqual(
- '\ngener \nfebrer \nmar\xe7 \nabril \nmaig \njuny \njuliol \nagost \nsetembre \noctubre \nnovembre \ndesembre \n \n\n1 \n2 \n3 \n4 \n5 \n6 \n7 \n8 \n9 \n10 \n11 \n12 \n13 \n14 \n15 \n16 \n17 \n18 \n19 \n20 \n21 \n22 \n23 \n24 \n25 \n26 \n27 \n28 \n29 \n30 \n31 \n \n\n2009 \n2010 \n2011 \n2012 \n2013 \n2014 \n2015 \n2016 \n2017 \n2018 \n ',
+ '\n--- \ngener \nfebrer \nmar\xe7 \nabril \nmaig \njuny \njuliol \nagost \nsetembre \noctubre \nnovembre \ndesembre \n \n\n--- \n1 \n2 \n3 \n4 \n5 \n6 \n7 \n8 \n9 \n10 \n11 \n12 \n13 \n14 \n15 \n16 \n17 \n18 \n19 \n20 \n21 \n22 \n23 \n24 \n25 \n26 \n27 \n28 \n29 \n30 \n31 \n \n\n--- \n2009 \n2010 \n2011 \n2012 \n2013 \n2014 \n2015 \n2016 \n2017 \n2018 \n ',
SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31))
)
@@ -508,6 +509,7 @@ class FormattingTests(TransRealMixin, TestCase):
fr_formats.FIRST_DAY_OF_WEEK = backup_FIRST_DAY_OF_WEEK
def test_l10n_enabled(self):
+ self.maxDiff = 3000
# Catalan locale
with translation.override('ca', deactivate=True):
self.assertEqual('j \d\e F \d\e Y', get_format('DATE_FORMAT'))
@@ -592,14 +594,14 @@ class FormattingTests(TransRealMixin, TestCase):
self.assertEqual(True, form5.is_valid())
self.assertEqual(datetime.date(2009, 12, 31), form5.cleaned_data['date_field'])
self.assertHTMLEqual(
- '\n1 \n2 \n3 \n4 \n5 \n6 \n7 \n8 \n9 \n10 \n11 \n12 \n13 \n14 \n15 \n16 \n17 \n18 \n19 \n20 \n21 \n22 \n23 \n24 \n25 \n26 \n27 \n28 \n29 \n30 \n31 \n \n\ngener \nfebrer \nmar\xe7 \nabril \nmaig \njuny \njuliol \nagost \nsetembre \noctubre \nnovembre \ndesembre \n \n\n2009 \n2010 \n2011 \n2012 \n2013 \n2014 \n2015 \n2016 \n2017 \n2018 \n ',
+ '\n--- \n1 \n2 \n3 \n4 \n5 \n6 \n7 \n8 \n9 \n10 \n11 \n12 \n13 \n14 \n15 \n16 \n17 \n18 \n19 \n20 \n21 \n22 \n23 \n24 \n25 \n26 \n27 \n28 \n29 \n30 \n31 \n \n\n--- \ngener \nfebrer \nmar\xe7 \nabril \nmaig \njuny \njuliol \nagost \nsetembre \noctubre \nnovembre \ndesembre \n \n\n--- \n2009 \n2010 \n2011 \n2012 \n2013 \n2014 \n2015 \n2016 \n2017 \n2018 \n ',
SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31))
)
# Russian locale (with E as month)
with translation.override('ru', deactivate=True):
self.assertHTMLEqual(
- '\n1 \n2 \n3 \n4 \n5 \n6 \n7 \n8 \n9 \n10 \n11 \n12 \n13 \n14 \n15 \n16 \n17 \n18 \n19 \n20 \n21 \n22 \n23 \n24 \n25 \n26 \n27 \n28 \n29 \n30 \n31 \n \n\n\u042f\u043d\u0432\u0430\u0440\u044c \n\u0424\u0435\u0432\u0440\u0430\u043b\u044c \n\u041c\u0430\u0440\u0442 \n\u0410\u043f\u0440\u0435\u043b\u044c \n\u041c\u0430\u0439 \n\u0418\u044e\u043d\u044c \n\u0418\u044e\u043b\u044c \n\u0410\u0432\u0433\u0443\u0441\u0442 \n\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c \n\u041e\u043a\u0442\u044f\u0431\u0440\u044c \n\u041d\u043e\u044f\u0431\u0440\u044c \n\u0414\u0435\u043a\u0430\u0431\u0440\u044c \n \n\n2009 \n2010 \n2011 \n2012 \n2013 \n2014 \n2015 \n2016 \n2017 \n2018 \n ',
+ '\n--- \n1 \n2 \n3 \n4 \n5 \n6 \n7 \n8 \n9 \n10 \n11 \n12 \n13 \n14 \n15 \n16 \n17 \n18 \n19 \n20 \n21 \n22 \n23 \n24 \n25 \n26 \n27 \n28 \n29 \n30 \n31 \n \n\n--- \n\u042f\u043d\u0432\u0430\u0440\u044c \n\u0424\u0435\u0432\u0440\u0430\u043b\u044c \n\u041c\u0430\u0440\u0442 \n\u0410\u043f\u0440\u0435\u043b\u044c \n\u041c\u0430\u0439 \n\u0418\u044e\u043d\u044c \n\u0418\u044e\u043b\u044c \n\u0410\u0432\u0433\u0443\u0441\u0442 \n\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c \n\u041e\u043a\u0442\u044f\u0431\u0440\u044c \n\u041d\u043e\u044f\u0431\u0440\u044c \n\u0414\u0435\u043a\u0430\u0431\u0440\u044c \n \n\n--- \n2009 \n2010 \n2011 \n2012 \n2013 \n2014 \n2015 \n2016 \n2017 \n2018 \n ',
SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31))
)
@@ -664,7 +666,7 @@ class FormattingTests(TransRealMixin, TestCase):
self.assertEqual(True, form6.is_valid())
self.assertEqual(datetime.date(2009, 12, 31), form6.cleaned_data['date_field'])
self.assertHTMLEqual(
- '\nJanuary \nFebruary \nMarch \nApril \nMay \nJune \nJuly \nAugust \nSeptember \nOctober \nNovember \nDecember \n \n\n1 \n2 \n3 \n4 \n5 \n6 \n7 \n8 \n9 \n10 \n11 \n12 \n13 \n14 \n15 \n16 \n17 \n18 \n19 \n20 \n21 \n22 \n23 \n24 \n25 \n26 \n27 \n28 \n29 \n30 \n31 \n \n\n2009 \n2010 \n2011 \n2012 \n2013 \n2014 \n2015 \n2016 \n2017 \n2018 \n ',
+ '\n--- \nJanuary \nFebruary \nMarch \nApril \nMay \nJune \nJuly \nAugust \nSeptember \nOctober \nNovember \nDecember \n \n\n--- \n1 \n2 \n3 \n4 \n5 \n6 \n7 \n8 \n9 \n10 \n11 \n12 \n13 \n14 \n15 \n16 \n17 \n18 \n19 \n20 \n21 \n22 \n23 \n24 \n25 \n26 \n27 \n28 \n29 \n30 \n31 \n \n\n--- \n2009 \n2010 \n2011 \n2012 \n2013 \n2014 \n2015 \n2016 \n2017 \n2018 \n ',
SelectDateWidget(years=range(2009, 2019)).render('mydate', datetime.date(2009, 12, 31))
)