summaryrefslogtreecommitdiff
path: root/django/forms/widgets.py
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2016-09-06 17:41:54 -0400
committerTim Graham <timograham@gmail.com>2016-09-22 12:20:58 -0400
commit3507d4e773aa9ff2336e7230ba231c4ba6eb568f (patch)
tree09467b4724131e91b0afe1d2f133e5e56ba068cf /django/forms/widgets.py
parent92323d54fd6df077dc523c423c7bb2dd8dbde621 (diff)
Fixed #27186 -- Fixed model form default fallback for MultiWidget, FileInput, SplitDateTimeWidget, SelectDateWidget, and SplitArrayWidget.
Thanks Matt Westcott for the review.
Diffstat (limited to 'django/forms/widgets.py')
-rw-r--r--django/forms/widgets.py27
1 files changed, 23 insertions, 4 deletions
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 4ed9c67ff2..f9cfaee9f9 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -236,6 +236,9 @@ class Widget(six.with_metaclass(RenameWidgetMethods)):
"""
return data.get(name)
+ def value_omitted_from_data(self, data, files, name):
+ return name not in data
+
def id_for_label(self, id_):
"""
Returns the HTML ID attribute of this Widget for use by a <label>,
@@ -351,6 +354,9 @@ class FileInput(Input):
"File widgets take data from FILES, not POST"
return files.get(name)
+ def value_omitted_from_data(self, data, files, name):
+ return name not in files
+
FILE_INPUT_CONTRADICTION = object()
@@ -481,10 +487,6 @@ def boolean_check(v):
class CheckboxInput(Widget):
- # Don't use model field defaults for fields that aren't in POST data,
- # because checkboxes don't appear in POST data if not checked.
- dont_use_model_field_default_for_empty_data = True
-
def __init__(self, attrs=None, check_test=None):
super(CheckboxInput, self).__init__(attrs)
# check_test is a callable that takes a value and returns True
@@ -510,6 +512,11 @@ class CheckboxInput(Widget):
value = values.get(value.lower(), value)
return bool(value)
+ def value_omitted_from_data(self, data, files, name):
+ # HTML checkboxes don't appear in POST data if not checked, so it's
+ # never known if the value is actually omitted.
+ return False
+
class Select(Widget):
allow_multiple_selected = False
@@ -876,6 +883,12 @@ class MultiWidget(Widget):
def value_from_datadict(self, data, files, name):
return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
+ def value_omitted_from_data(self, data, files, name):
+ return all(
+ widget.value_omitted_from_data(data, files, name + '_%s' % i)
+ for i, widget in enumerate(self.widgets)
+ )
+
def format_output(self, rendered_widgets):
"""
Given a list of rendered widgets (as strings), returns a Unicode string
@@ -1061,6 +1074,12 @@ class SelectDateWidget(Widget):
return '%s-%s-%s' % (y, m, d)
return data.get(name)
+ def value_omitted_from_data(self, data, files, name):
+ return not any(
+ ('{}_{}'.format(name, interval) in data)
+ for interval in ('year', 'month', 'day')
+ )
+
def create_select(self, name, field, value, val, choices, none_value):
if 'id' in self.attrs:
id_ = self.attrs['id']