Ticket #4752: div-form.3.diff

File div-form.3.diff, 5.2 KB (added by SmileyChris, 8 years ago)

simpler version with tests and first-pass docs

  • django/newforms/forms.py

     
    5757    # class is different than Form. See the comments by the Form class for more
    5858    # information. Any improvements to the form API should be made to *this*
    5959    # class, not to the Form class.
    60     def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None):
     60    def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None, error_list_class=None):
    6161        self.is_bound = data is not None
    6262        self.data = data or {}
    6363        self.auto_id = auto_id
    6464        self.prefix = prefix
    6565        self.initial = initial or {}
     66        if not error_list_class:
     67            error_list_class = ErrorList
     68        self.error_list_class = error_list_class
    6669        self._errors = None # Stores the errors after clean() has been called.
    6770
    6871        # The base_fields class attribute is the *class-wide* definition of
     
    116119        output, hidden_fields = [], []
    117120        for name, field in self.fields.items():
    118121            bf = BoundField(self, field, name)
    119             bf_errors = ErrorList([escape(error) for error in bf.errors]) # Escape and cache in local variable.
     122            bf_errors = self.error_list_class([escape(error) for error in bf.errors]) # Escape and cache in local variable.
    120123            if bf.is_hidden:
    121124                if bf_errors:
    122125                    top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors])
     
    167170        field -- i.e., from Form.clean(). Returns an empty ErrorList if there
    168171        are none.
    169172        """
    170         return self.errors.get(NON_FIELD_ERRORS, ErrorList())
     173        return self.errors.get(NON_FIELD_ERRORS, self.error_list_class())
    171174
    172175    def full_clean(self):
    173176        """
     
    248251        Returns an ErrorList for this field. Returns an empty ErrorList
    249252        if there are none.
    250253        """
    251         return self.form.errors.get(self.name, ErrorList())
     254        return self.form.errors.get(self.name, self.form.error_list_class())
    252255    errors = property(_errors)
    253256
    254257    def as_widget(self, widget, attrs=None):
  • docs/newforms.txt

     
    554554    <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
    555555    <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
    556556
     557Customizing the error list format
     558~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     559
     560By default, forms use ``django.newforms.util.ErrorList`` to output validation
     561errors. If you would like to use an alternate form of displaying errors, you
     562can tell your forms to use a different output format. For example::
     563
     564    >>> from django.newforms.util import ErrorList
     565    >>> class DivErrorList(ErrorList):
     566    ...     def __str__(self):
     567    ...         return self.as_divs()
     568    ...     def as_divs(self):
     569    ...         if not self: return u''
     570    ...         return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self])
     571    >>> f = ContactForm(data, auto_id=False, error_list_class=DivErrorList)
     572    >>> f.as_p()
     573    <div class="errorlist"><div class="error">This field is required.</div></div>
     574    <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
     575    <p>Message: <input type="text" name="message" value="Hi there" /></p>
     576    <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
     577    <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
     578    <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
     579
    557580More granular output
    558581~~~~~~~~~~~~~~~~~~~~
    559582
  • tests/regressiontests/forms/tests.py

     
    36903690True
    36913691>>> f.cleaned_data['username']
    36923692u'sirrobin'
     3693
     3694#######################################
     3695# Test overriding ErrorList in a form #
     3696#######################################
     3697
     3698>>> from django.newforms.util import ErrorList
     3699>>> class DivErrorList(ErrorList):
     3700...     def __str__(self):
     3701...         return self.as_divs()
     3702...     def as_divs(self):
     3703...         if not self: return u''
     3704...         return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self])
     3705>>> class CommentForm(Form):
     3706...     name = CharField(max_length=50, required=False)
     3707...     email = EmailField()
     3708...     comment = CharField()
     3709>>> data = dict(email='invalid')
     3710>>> f = CommentForm(data, auto_id=False, error_list_class=DivErrorList)
     3711>>> print f.as_p()
     3712<p>Name: <input type="text" name="name" maxlength="50" /></p>
     3713<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
     3714<p>Email: <input type="text" name="email" value="invalid" /></p>
     3715<div class="errorlist"><div class="error">This field is required.</div></div>
     3716<p>Comment: <input type="text" name="comment" /></p>
     3717
    36933718"""
    36943719
    36953720__test__ = {
Back to Top