Fixed #22318 -- Added Form.has_error() to easily check if a given error has happened.
This commit is contained in:
parent
3f7615cddc
commit
7ac8380799
|
@ -334,6 +334,15 @@ class BaseForm(object):
|
||||||
if field in self.cleaned_data:
|
if field in self.cleaned_data:
|
||||||
del self.cleaned_data[field]
|
del self.cleaned_data[field]
|
||||||
|
|
||||||
|
def has_error(self, field, code=None):
|
||||||
|
if code is None:
|
||||||
|
return field in self.errors
|
||||||
|
if field in self.errors:
|
||||||
|
for error in self.errors.as_data()[field]:
|
||||||
|
if error.code == code:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def full_clean(self):
|
def full_clean(self):
|
||||||
"""
|
"""
|
||||||
Cleans all of self.data and populates self._errors and
|
Cleans all of self.data and populates self._errors and
|
||||||
|
|
|
@ -182,6 +182,17 @@ when defining form errors.
|
||||||
Note that ``Form.add_error()`` automatically removes the relevant field from
|
Note that ``Form.add_error()`` automatically removes the relevant field from
|
||||||
``cleaned_data``.
|
``cleaned_data``.
|
||||||
|
|
||||||
|
.. method:: Form.has_error(field, code=None)
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
This method returns a boolean designating whether a field has an error with
|
||||||
|
a specific error ``code``. If ``code`` is ``None``, it will return ``True``
|
||||||
|
if the field contains any errors at all.
|
||||||
|
|
||||||
|
To check for non-field errors use
|
||||||
|
:data:`~django.core.exceptions.NON_FIELD_ERRORS` as the ``field`` parameter.
|
||||||
|
|
||||||
Behavior of unbound forms
|
Behavior of unbound forms
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,9 @@ Forms
|
||||||
* Form widgets now render attributes with a value of ``True`` or ``False``
|
* Form widgets now render attributes with a value of ``True`` or ``False``
|
||||||
as HTML5 boolean attributes.
|
as HTML5 boolean attributes.
|
||||||
|
|
||||||
|
* The new :meth:`~django.forms.Form.has_error()` method allows checking
|
||||||
|
if a specific error has happened.
|
||||||
|
|
||||||
Internationalization
|
Internationalization
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import datetime
|
||||||
import json
|
import json
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
from django.core.exceptions import NON_FIELD_ERRORS
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.core.validators import RegexValidator
|
from django.core.validators import RegexValidator
|
||||||
from django.forms import (
|
from django.forms import (
|
||||||
|
@ -739,6 +740,39 @@ class FormsTestCase(TestCase):
|
||||||
with six.assertRaisesRegex(self, ValueError, "has no field named"):
|
with six.assertRaisesRegex(self, ValueError, "has no field named"):
|
||||||
f.add_error('missing_field', 'Some error.')
|
f.add_error('missing_field', 'Some error.')
|
||||||
|
|
||||||
|
def test_has_error(self):
|
||||||
|
class UserRegistration(Form):
|
||||||
|
username = CharField(max_length=10)
|
||||||
|
password1 = CharField(widget=PasswordInput, min_length=5)
|
||||||
|
password2 = CharField(widget=PasswordInput)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
if (self.cleaned_data.get('password1') and self.cleaned_data.get('password2')
|
||||||
|
and self.cleaned_data['password1'] != self.cleaned_data['password2']):
|
||||||
|
raise ValidationError(
|
||||||
|
'Please make sure your passwords match.',
|
||||||
|
code='password_mismatch',
|
||||||
|
)
|
||||||
|
|
||||||
|
f = UserRegistration(data={})
|
||||||
|
self.assertTrue(f.has_error('password1'))
|
||||||
|
self.assertTrue(f.has_error('password1', 'required'))
|
||||||
|
self.assertFalse(f.has_error('password1', 'anything'))
|
||||||
|
|
||||||
|
f = UserRegistration(data={'password1': 'Hi', 'password2': 'Hi'})
|
||||||
|
self.assertTrue(f.has_error('password1'))
|
||||||
|
self.assertTrue(f.has_error('password1', 'min_length'))
|
||||||
|
self.assertFalse(f.has_error('password1', 'anything'))
|
||||||
|
self.assertFalse(f.has_error('password2'))
|
||||||
|
self.assertFalse(f.has_error('password2', 'anything'))
|
||||||
|
|
||||||
|
f = UserRegistration(data={'password1': 'Bonjour', 'password2': 'Hello'})
|
||||||
|
self.assertFalse(f.has_error('password1'))
|
||||||
|
self.assertFalse(f.has_error('password1', 'required'))
|
||||||
|
self.assertTrue(f.has_error(NON_FIELD_ERRORS))
|
||||||
|
self.assertTrue(f.has_error(NON_FIELD_ERRORS, 'password_mismatch'))
|
||||||
|
self.assertFalse(f.has_error(NON_FIELD_ERRORS, 'anything'))
|
||||||
|
|
||||||
def test_dynamic_construction(self):
|
def test_dynamic_construction(self):
|
||||||
# It's possible to construct a Form dynamically by adding to the self.fields
|
# 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
|
# dictionary in __init__(). Don't forget to call Form.__init__() within the
|
||||||
|
|
Loading…
Reference in New Issue