diff options
| author | RobertAKARobin <robertgfthomas@gmail.com> | 2019-05-31 12:05:37 -0500 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-06-04 08:28:49 +0200 |
| commit | aa94f7c899b98f547fc1d26797ba892c38eaf415 (patch) | |
| tree | 0cf5d8df8f304489b4af34c720e374931f5feafd | |
| parent | 21b1d239125f1228e579b1ce8d94d4d5feadd2a6 (diff) | |
Fixed #30534 -- Fixed overriding a field's default in ModelForm.cleaned_data().
| -rw-r--r-- | django/forms/models.py | 7 | ||||
| -rw-r--r-- | tests/model_forms/tests.py | 26 |
2 files changed, 31 insertions, 2 deletions
diff --git a/django/forms/models.py b/django/forms/models.py index 5edbbd376f..3ad8cea9b6 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -48,8 +48,11 @@ 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[f.name].field.widget.value_omitted_from_data(form.data, form.files, form.add_prefix(f.name))): + if ( + f.has_default() and + form[f.name].field.widget.value_omitted_from_data(form.data, form.files, form.add_prefix(f.name)) and + cleaned_data.get(f.name) in form[f.name].field.empty_values + ): 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/tests/model_forms/tests.py b/tests/model_forms/tests.py index 3893eb334c..42b9cf2c45 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -585,6 +585,32 @@ class ModelFormBaseTest(TestCase): m2 = mf2.save(commit=False) self.assertEqual(m2.mode, '') + def test_default_not_populated_on_non_empty_value_in_cleaned_data(self): + class PubForm(forms.ModelForm): + mode = forms.CharField(max_length=255, required=False) + mocked_mode = None + + def clean(self): + self.cleaned_data['mode'] = self.mocked_mode + return self.cleaned_data + + class Meta: + model = PublicationDefaults + fields = ('mode',) + + pub_form = PubForm({}) + pub_form.mocked_mode = 'de' + pub = pub_form.save(commit=False) + self.assertEqual(pub.mode, 'de') + # Default should be populated on an empty value in cleaned_data. + default_mode = 'di' + for empty_value in pub_form.fields['mode'].empty_values: + with self.subTest(empty_value=empty_value): + pub_form = PubForm({}) + pub_form.mocked_mode = empty_value + pub = pub_form.save(commit=False) + self.assertEqual(pub.mode, default_mode) + def test_default_not_populated_on_optional_checkbox_input(self): class PubForm(forms.ModelForm): class Meta: |
