diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 0f861f0046..c0e3349aba 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -911,7 +911,7 @@ class SelectDateWidget(Widget):
This also serves as an example of a Widget that has more than one HTML
element and hence implements value_from_datadict.
"""
- none_value = (0, '---')
+ none_value = ('', '---')
month_field = '%s_month'
day_field = '%s_day'
year_field = '%s_year'
@@ -941,12 +941,12 @@ class SelectDateWidget(Widget):
if not len(empty_label) == 3:
raise ValueError('empty_label list/tuple must have 3 elements.')
- self.year_none_value = (0, empty_label[0])
- self.month_none_value = (0, empty_label[1])
- self.day_none_value = (0, empty_label[2])
+ self.year_none_value = ('', empty_label[0])
+ self.month_none_value = ('', empty_label[1])
+ self.day_none_value = ('', empty_label[2])
else:
if empty_label is not None:
- self.none_value = (0, empty_label)
+ self.none_value = ('', empty_label)
self.year_none_value = self.none_value
self.month_none_value = self.none_value
@@ -1006,7 +1006,9 @@ class SelectDateWidget(Widget):
elif isinstance(value, str):
match = self.date_re.match(value)
if match:
- year, month, day = [int(val) for val in match.groups()]
+ # Convert any zeros in the date to empty strings to match the
+ # empty option value.
+ year, month, day = [int(val) or '' for val in match.groups()]
elif settings.USE_L10N:
input_format = get_format('DATE_INPUT_FORMATS')[0]
try:
@@ -1042,20 +1044,21 @@ class SelectDateWidget(Widget):
y = data.get(self.year_field % name)
m = data.get(self.month_field % name)
d = data.get(self.day_field % name)
- if y == m == d == "0":
+ if y == m == d == '':
return None
- if y and m and d:
+ if y is not None and m is not None and d is not None:
if settings.USE_L10N:
input_format = get_format('DATE_INPUT_FORMATS')[0]
try:
date_value = datetime.date(int(y), int(m), int(d))
except ValueError:
- return '%s-%s-%s' % (y, m, d)
+ pass
else:
date_value = datetime_safe.new_date(date_value)
return date_value.strftime(input_format)
- else:
- return '%s-%s-%s' % (y, m, d)
+ # Return pseudo-ISO dates with zeros for any unselected values,
+ # e.g. '2017-0-23'.
+ return '%s-%s-%s' % (y or 0, m or 0, d or 0)
return data.get(name)
def value_omitted_from_data(self, data, files, name):
diff --git a/docs/releases/2.1.txt b/docs/releases/2.1.txt
index 03d80115d3..a2aa2e8379 100644
--- a/docs/releases/2.1.txt
+++ b/docs/releases/2.1.txt
@@ -265,6 +265,10 @@ Miscellaneous
elements, e.g. `` ``. This is incompatible within XHTML, although some
widgets already used aspects of HTML5 such as boolean attributes.
+* The value of :class:`~django.forms.SelectDateWidget`'s empty options is
+ changed from 0 to an empty string, which mainly may require some adjustments
+ in tests that compare HTML.
+
.. _deprecated-features-2.1:
Features deprecated in 2.1
diff --git a/tests/forms_tests/widget_tests/test_selectdatewidget.py b/tests/forms_tests/widget_tests/test_selectdatewidget.py
index c0e82c69a0..1fe72ca8fb 100644
--- a/tests/forms_tests/widget_tests/test_selectdatewidget.py
+++ b/tests/forms_tests/widget_tests/test_selectdatewidget.py
@@ -18,7 +18,7 @@ class SelectDateWidgetTest(WidgetTest):
self.check_html(self.widget, 'mydate', '', html=(
"""