summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaap Roes <jroes@leukeleu.nl>2021-09-22 13:28:49 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-09-24 10:50:41 +0200
commit7fe9b6f6df16fa875fe360a1c7d0ac53fcf08a53 (patch)
treeead0be8331d611c1af7c05234334638b8bc4568c
parentb1bf8c8a4ba04049dc19217bf0e876488a4fae3c (diff)
Fixed #33130 -- Restored form errors to be a dict.
Regression in 456466d932830b096d39806e291fe23ec5ed38d5.
-rw-r--r--django/forms/utils.py8
-rw-r--r--tests/forms_tests/tests/test_forms.py1
-rw-r--r--tests/forms_tests/tests/test_utils.py46
3 files changed, 51 insertions, 4 deletions
diff --git a/django/forms/utils.py b/django/forms/utils.py
index 44447b5cf5..4af57e8586 100644
--- a/django/forms/utils.py
+++ b/django/forms/utils.py
@@ -1,5 +1,5 @@
import json
-from collections import UserDict, UserList
+from collections import UserList
from django.conf import settings
from django.core.exceptions import ValidationError
@@ -84,7 +84,7 @@ class RenderableErrorMixin(RenderableMixin):
return self.render(self.template_name_ul)
-class ErrorDict(UserDict, RenderableErrorMixin):
+class ErrorDict(dict, RenderableErrorMixin):
"""
A collection of errors that knows how to display itself in various formats.
@@ -94,8 +94,8 @@ class ErrorDict(UserDict, RenderableErrorMixin):
template_name_text = 'django/forms/errors/dict/text.txt'
template_name_ul = 'django/forms/errors/dict/ul.html'
- def __init__(self, data=None, renderer=None):
- super().__init__(data)
+ def __init__(self, *args, renderer=None, **kwargs):
+ super().__init__(*args, **kwargs)
self.renderer = renderer or get_default_renderer()
def as_data(self):
diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py
index 9af103dbd8..fefebde05c 100644
--- a/tests/forms_tests/tests/test_forms.py
+++ b/tests/forms_tests/tests/test_forms.py
@@ -67,6 +67,7 @@ class FormsTestCase(SimpleTestCase):
self.assertTrue(p.is_bound)
self.assertEqual(p.errors, {})
+ self.assertIsInstance(p.errors, dict)
self.assertTrue(p.is_valid())
self.assertHTMLEqual(p.errors.as_ul(), '')
self.assertEqual(p.errors.as_text(), '')
diff --git a/tests/forms_tests/tests/test_utils.py b/tests/forms_tests/tests/test_utils.py
index ea0949920e..e0e9a0e22e 100644
--- a/tests/forms_tests/tests/test_utils.py
+++ b/tests/forms_tests/tests/test_utils.py
@@ -1,4 +1,5 @@
import copy
+import json
from django.core.exceptions import ValidationError
from django.forms.utils import ErrorDict, ErrorList, flatatt
@@ -162,3 +163,48 @@ class FormsUtilsTestCase(SimpleTestCase):
e = ErrorList(['Invalid username.'])
self.assertTrue(hasattr(ErrorList, '__html__'))
self.assertEqual(str(e), e.__html__())
+
+ def test_error_dict_is_dict(self):
+ self.assertIsInstance(ErrorDict(), dict)
+
+ def test_error_dict_is_json_serializable(self):
+ init_errors = ErrorDict([
+ ('__all__', ErrorList([
+ ValidationError('Sorry this form only works on leap days.')
+ ])),
+ ('name', ErrorList([ValidationError('This field is required.')])),
+ ])
+ min_value_error_list = ErrorList([
+ ValidationError('Ensure this value is greater than or equal to 0.')
+ ])
+ e = ErrorDict(
+ init_errors,
+ date=ErrorList([
+ ErrorDict({
+ 'day': min_value_error_list,
+ 'month': min_value_error_list,
+ 'year': min_value_error_list,
+ }),
+ ]),
+ )
+ e['renderer'] = ErrorList([
+ ValidationError(
+ 'Select a valid choice. That choice is not one of the '
+ 'available choices.'
+ ),
+ ])
+ self.assertJSONEqual(json.dumps(e), {
+ '__all__': ['Sorry this form only works on leap days.'],
+ 'name': ['This field is required.'],
+ 'date': [
+ {
+ 'day': ['Ensure this value is greater than or equal to 0.'],
+ 'month': ['Ensure this value is greater than or equal to 0.'],
+ 'year': ['Ensure this value is greater than or equal to 0.'],
+ },
+ ],
+ 'renderer': [
+ 'Select a valid choice. That choice is not one of the '
+ 'available choices.'
+ ],
+ })