From 25904db9154c5be3ecda9585d96f536841af9126 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Wed, 26 Oct 2022 19:05:27 +1100 Subject: [PATCH] Fixed #34119 -- Prevented callable default hidden widget value from being overridden. Thanks to Benjamin Rigaud for the report. --- django/forms/boundfield.py | 10 +++++++- tests/forms_tests/tests/tests.py | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/django/forms/boundfield.py b/django/forms/boundfield.py index 9f2ae59ab442..6764276148ed 100644 --- a/django/forms/boundfield.py +++ b/django/forms/boundfield.py @@ -96,9 +96,17 @@ def as_widget(self, widget=None, attrs=None, only_initial=False): attrs.setdefault( "id", self.html_initial_id if only_initial else self.auto_id ) + if only_initial and self.html_initial_name in self.form.data: + # Propagate the hidden initial value. + value = self.form._widget_data_value( + self.field.hidden_widget(), + self.html_initial_name, + ) + else: + value = self.value() return widget.render( name=self.html_initial_name if only_initial else self.html_name, - value=self.value(), + value=value, attrs=attrs, renderer=self.form.renderer, ) diff --git a/tests/forms_tests/tests/tests.py b/tests/forms_tests/tests/tests.py index aba405db1515..294e57416858 100644 --- a/tests/forms_tests/tests/tests.py +++ b/tests/forms_tests/tests/tests.py @@ -203,6 +203,46 @@ def test_initial_instance_value(self): """, ) + def test_callable_default_hidden_widget_value_not_overridden(self): + class FieldWithCallableDefaultsModel(models.Model): + int_field = models.IntegerField(default=lambda: 1) + json_field = models.JSONField(default=dict) + + class FieldWithCallableDefaultsModelForm(ModelForm): + class Meta: + model = FieldWithCallableDefaultsModel + fields = "__all__" + + form = FieldWithCallableDefaultsModelForm( + data={ + "initial-int_field": "1", + "int_field": "1000", + "initial-json_field": "{}", + "json_field": '{"key": "val"}', + } + ) + form_html = form.as_p() + self.assertHTMLEqual( + form_html, + """ +

+ + + +

+

+ + + +

+ """, + ) + class FormsModelTestCase(TestCase): def test_unicode_filename(self):