diff --git a/django/newforms/forms.py b/django/newforms/forms.py index 906978c86f..5baf0a079b 100644 --- a/django/newforms/forms.py +++ b/django/newforms/forms.py @@ -57,13 +57,15 @@ class BaseForm(StrAndUnicode): # class is different than Form. See the comments by the Form class for more # information. Any improvements to the form API should be made to *this* # class, not to the Form class. - def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None): + def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, + initial=None, error_class=ErrorList): self.is_bound = data is not None or files is not None self.data = data or {} self.files = files or {} self.auto_id = auto_id self.prefix = prefix self.initial = initial or {} + self.error_class = error_class self._errors = None # Stores the errors after clean() has been called. # The base_fields class attribute is the *class-wide* definition of @@ -117,7 +119,7 @@ class BaseForm(StrAndUnicode): output, hidden_fields = [], [] for name, field in self.fields.items(): bf = BoundField(self, field, name) - bf_errors = ErrorList([escape(error) for error in bf.errors]) # Escape and cache in local variable. + bf_errors = self.error_class([escape(error) for error in bf.errors]) # Escape and cache in local variable. if bf.is_hidden: if bf_errors: top_errors.extend(['(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors]) @@ -168,7 +170,7 @@ class BaseForm(StrAndUnicode): field -- i.e., from Form.clean(). Returns an empty ErrorList if there are none. """ - return self.errors.get(NON_FIELD_ERRORS, ErrorList()) + return self.errors.get(NON_FIELD_ERRORS, self.error_class()) def full_clean(self): """ @@ -241,7 +243,7 @@ class BoundField(StrAndUnicode): Returns an ErrorList for this field. Returns an empty ErrorList if there are none. """ - return self.form.errors.get(self.name, ErrorList()) + return self.form.errors.get(self.name, self.form.error_class()) errors = property(_errors) def as_widget(self, widget=None, attrs=None): diff --git a/docs/newforms.txt b/docs/newforms.txt index 32c4441eb2..33625f39b8 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -554,6 +554,29 @@ method you're using::

Sender:

Cc myself:

+Customizing the error list format +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, forms use ``django.newforms.util.ErrorList`` to format validation +errors. If you'd like to use an alternate class for displaying errors, you can +pass that in at construction time:: + + >>> from django.newforms.util import ErrorList + >>> class DivErrorList(ErrorList): + ... def __unicode__(self): + ... return self.as_divs() + ... def as_divs(self): + ... if not self: return u'' + ... return u'
%s
' % ''.join([u'
%s
' % e for e in self]) + >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList) + >>> f.as_p() +
This field is required.
+

Subject:

+

Message:

+
Enter a valid e-mail address.
+

Sender:

+

Cc myself:

+ More granular output ~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index 0df3ee3858..2477eb1cef 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -3821,6 +3821,31 @@ u'' True >>> f.cleaned_data['username'] u'sirrobin' + +####################################### +# Test overriding ErrorList in a form # +####################################### + +>>> from django.newforms.util import ErrorList +>>> class DivErrorList(ErrorList): +... def __unicode__(self): +... return self.as_divs() +... def as_divs(self): +... if not self: return u'' +... return u'
%s
' % ''.join([u'
%s
' % e for e in self]) +>>> class CommentForm(Form): +... name = CharField(max_length=50, required=False) +... email = EmailField() +... comment = CharField() +>>> data = dict(email='invalid') +>>> f = CommentForm(data, auto_id=False, error_class=DivErrorList) +>>> print f.as_p() +

Name:

+
Enter a valid e-mail address.
+

Email:

+
This field is required.
+

Comment:

+ """ __test__ = {