From 0b59ea3343ef6f035064cfae1608f54c5a3fd147 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Tue, 6 Sep 2016 17:41:54 -0400 Subject: [PATCH] [1.10.x] Fixed #27186 -- Fixed model form default fallback for MultiWidget, FileInput, SplitDateTimeWidget, SelectDateWidget, and SplitArrayWidget. Thanks Matt Westcott for the review. Backport of 3507d4e773aa9ff2336e7230ba231c4ba6eb568f from master --- django/contrib/postgres/forms/array.py | 6 +++ django/forms/models.py | 4 +- django/forms/widgets.py | 27 ++++++++-- docs/ref/forms/widgets.txt | 15 ++++++ docs/releases/1.10.2.txt | 5 ++ docs/topics/forms/modelforms.txt | 16 ++++-- .../widget_tests/test_checkboxinput.py | 4 ++ .../widget_tests/test_fileinput.py | 4 ++ .../widget_tests/test_multiwidget.py | 7 +++ .../widget_tests/test_selectdatewidget.py | 8 +++ tests/forms_tests/widget_tests/test_widget.py | 12 +++++ tests/model_forms/models.py | 2 + tests/model_forms/tests.py | 52 +++++++++++++++++++ tests/postgres_tests/models.py | 2 +- tests/postgres_tests/test_array.py | 27 +++++++++- 15 files changed, 178 insertions(+), 13 deletions(-) create mode 100644 tests/forms_tests/widget_tests/test_widget.py diff --git a/django/contrib/postgres/forms/array.py b/django/contrib/postgres/forms/array.py index dd9ac1178e..bd3daaae0b 100644 --- a/django/contrib/postgres/forms/array.py +++ b/django/contrib/postgres/forms/array.py @@ -103,6 +103,12 @@ class SplitArrayWidget(forms.Widget): return [self.widget.value_from_datadict(data, files, '%s_%s' % (name, index)) for index in range(self.size)] + def value_omitted_from_data(self, data, files, name): + return all( + self.widget.value_omitted_from_data(data, files, '%s_%s' % (name, index)) + for index in range(self.size) + ) + def id_for_label(self, id_): # See the comment for RadioSelect.id_for_label() if id_: diff --git a/django/forms/models.py b/django/forms/models.py index 1d54ea9676..ce93dead9e 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -54,8 +54,8 @@ def construct_instance(form, instance, fields=None, exclude=None): continue # Leave defaults for fields that aren't in POST data, except for # checkbox inputs because they don't appear in POST data if not checked. - if (f.has_default() and form.add_prefix(f.name) not in form.data and - not getattr(form[f.name].field.widget, 'dont_use_model_field_default_for_empty_data', False)): + if (f.has_default() and + form[f.name].field.widget.value_omitted_from_data(form.data, form.files, form.add_prefix(f.name))): continue # Defer saving file-type fields until after the other fields, so a # callable upload_to can use the values from other fields. diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 735207aa80..965f84f7df 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -237,6 +237,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