diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-09-13 23:09:40 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-09-13 23:09:40 +0000 |
| commit | ce249d4366a800ebc033cefb8beb33b9b0dba051 (patch) | |
| tree | 0aed8ce6a10997658e4aa177e622fe29304a4a2f | |
| parent | a7d0ad67dcd6e47d4905331187def49271ad8084 (diff) | |
Fixed #4752 -- Make default ErrorList customisable in newforms display. Based on a patch from michal@logix.cz and SmileyChris.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6142 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/newforms/forms.py | 10 | ||||
| -rw-r--r-- | docs/newforms.txt | 23 | ||||
| -rw-r--r-- | tests/regressiontests/forms/tests.py | 25 |
3 files changed, 54 insertions, 4 deletions
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:: <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p> <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p> +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'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self]) + >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList) + >>> f.as_p() + <div class="errorlist"><div class="error">This field is required.</div></div> + <p>Subject: <input type="text" name="subject" maxlength="100" /></p> + <p>Message: <input type="text" name="message" value="Hi there" /></p> + <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div> + <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p> + <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p> + 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'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % 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() +<p>Name: <input type="text" name="name" maxlength="50" /></p> +<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div> +<p>Email: <input type="text" name="email" value="invalid" /></p> +<div class="errorlist"><div class="error">This field is required.</div></div> +<p>Comment: <input type="text" name="comment" /></p> + """ __test__ = { |
