summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/forms/forms.py3
-rw-r--r--django/forms/utils.py5
-rw-r--r--tests/forms_tests/tests/test_forms.py16
3 files changed, 23 insertions, 1 deletions
diff --git a/django/forms/forms.py b/django/forms/forms.py
index a601467e18..81c59dea33 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -191,7 +191,8 @@ class BaseForm:
def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row):
"Output HTML. Used by as_table(), as_ul(), as_p()."
- top_errors = self.non_field_errors() # Errors that should be displayed above all fields.
+ # Errors that should be displayed above all fields.
+ top_errors = self.non_field_errors().copy()
output, hidden_fields = [], []
for name, field in self.fields.items():
diff --git a/django/forms/utils.py b/django/forms/utils.py
index 5ae137943a..fbe79f1142 100644
--- a/django/forms/utils.py
+++ b/django/forms/utils.py
@@ -92,6 +92,11 @@ class ErrorList(UserList, list):
def as_data(self):
return ValidationError(self.data).error_list
+ def copy(self):
+ copy = super().copy()
+ copy.error_class = self.error_class
+ return copy
+
def get_json_data(self, escape_html=False):
errors = []
for error in self.as_data():
diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py
index e4a8127e15..b62b32de4b 100644
--- a/tests/forms_tests/tests/test_forms.py
+++ b/tests/forms_tests/tests/test_forms.py
@@ -1245,6 +1245,22 @@ value="Should escape < & > and <script>alert('xss')&lt
self.assertTrue(f.has_error(NON_FIELD_ERRORS, 'password_mismatch'))
self.assertFalse(f.has_error(NON_FIELD_ERRORS, 'anything'))
+ def test_html_output_with_hidden_input_field_errors(self):
+ class TestForm(Form):
+ hidden_input = CharField(widget=HiddenInput)
+
+ def clean(self):
+ self.add_error(None, 'Form error')
+
+ f = TestForm(data={})
+ error_dict = {
+ 'hidden_input': ['This field is required.'],
+ '__all__': ['Form error'],
+ }
+ self.assertEqual(f.errors, error_dict)
+ f.as_table()
+ self.assertEqual(f.errors, error_dict)
+
def test_dynamic_construction(self):
# It's possible to construct a Form dynamically by adding to the self.fields
# dictionary in __init__(). Don't forget to call Form.__init__() within the