diff --git a/django/newforms/forms.py b/django/newforms/forms.py
index 2c481e4..c01a59b 100644
a
|
b
|
class BaseForm(StrAndUnicode):
|
64 | 64 | # information. Any improvements to the form API should be made to *this* |
65 | 65 | # class, not to the Form class. |
66 | 66 | def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, |
67 | | initial=None, error_class=ErrorList, label_suffix=':'): |
| 67 | initial=None, error_class=ErrorDict, label_suffix=':'): |
68 | 68 | self.is_bound = data is not None or files is not None |
69 | 69 | self.data = data or {} |
70 | 70 | self.files = files or {} |
… |
… |
class BaseForm(StrAndUnicode):
|
126 | 126 | output, hidden_fields = [], [] |
127 | 127 | for name, field in self.fields.items(): |
128 | 128 | bf = BoundField(self, field, name) |
129 | | bf_errors = self.error_class([escape(error) for error in bf.errors]) # Escape and cache in local variable. |
| 129 | bf_errors = bf.errors # Escape and cache in local variable. |
130 | 130 | if bf.is_hidden: |
131 | 131 | if bf_errors: |
132 | 132 | top_errors.extend([u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors]) |
… |
… |
class BaseForm(StrAndUnicode):
|
182 | 182 | field -- i.e., from Form.clean(). Returns an empty ErrorList if there |
183 | 183 | are none. |
184 | 184 | """ |
185 | | return self.errors.get(NON_FIELD_ERRORS, self.error_class()) |
| 185 | return self.errors.get(NON_FIELD_ERRORS) |
186 | 186 | |
187 | 187 | def full_clean(self): |
188 | 188 | """ |
189 | 189 | Cleans all of self.data and populates self._errors and |
190 | 190 | self.cleaned_data. |
191 | 191 | """ |
192 | | self._errors = ErrorDict() |
| 192 | self._errors = self.error_class() |
193 | 193 | if not self.is_bound: # Stop further processing. |
194 | 194 | return |
195 | 195 | self.cleaned_data = {} |
… |
… |
class BoundField(StrAndUnicode):
|
269 | 269 | Returns an ErrorList for this field. Returns an empty ErrorList |
270 | 270 | if there are none. |
271 | 271 | """ |
272 | | return self.form.errors.get(self.name, self.form.error_class()) |
| 272 | return self.form.errors.get(self.name) |
273 | 273 | errors = property(_errors) |
274 | 274 | |
275 | 275 | def as_widget(self, widget=None, attrs=None): |
diff --git a/django/newforms/util.py b/django/newforms/util.py
index b3edf41..a7f2162 100644
a
|
b
|
def flatatt(attrs):
|
12 | 12 | """ |
13 | 13 | return u''.join([u' %s="%s"' % (k, escape(v)) for k, v in attrs.items()]) |
14 | 14 | |
15 | | class ErrorDict(dict, StrAndUnicode): |
| 15 | class ErrorList(list, StrAndUnicode): |
16 | 16 | """ |
17 | 17 | A collection of errors that knows how to display itself in various formats. |
18 | | |
19 | | The dictionary keys are the field names, and the values are the errors. |
20 | 18 | """ |
21 | 19 | def __unicode__(self): |
22 | 20 | return self.as_ul() |
… |
… |
class ErrorDict(dict, StrAndUnicode):
|
24 | 22 | def as_ul(self): |
25 | 23 | if not self: return u'' |
26 | 24 | return mark_safe(u'<ul class="errorlist">%s</ul>' |
27 | | % ''.join([u'<li>%s%s</li>' % (k, force_unicode(v)) |
28 | | for k, v in self.items()])) |
| 25 | % ''.join([u'<li>%s</li>' % escape(e) for e in self])) |
29 | 26 | |
30 | 27 | def as_text(self): |
31 | | return u'\n'.join([u'* %s\n%s' % (k, u'\n'.join([u' * %s' % force_unicode(i) for i in v])) for k, v in self.items()]) |
| 28 | if not self: return u'' |
| 29 | return u'\n'.join([u'* %s' % force_unicode(e) for e in self]) |
32 | 30 | |
33 | | class ErrorList(list, StrAndUnicode): |
| 31 | def __repr__(self): |
| 32 | return repr([force_unicode(e) for e in self]) |
| 33 | |
| 34 | class ErrorDict(dict, StrAndUnicode): |
34 | 35 | """ |
35 | 36 | A collection of errors that knows how to display itself in various formats. |
| 37 | |
| 38 | The dictionary keys are the field names, and the values are the errors. |
36 | 39 | """ |
| 40 | error_class = ErrorList |
| 41 | |
37 | 42 | def __unicode__(self): |
38 | 43 | return self.as_ul() |
39 | 44 | |
| 45 | def __getitem__(self, key): |
| 46 | value = super(ErrorDict, self).__getitem__(key) |
| 47 | if value: |
| 48 | return self.error_class(value) |
| 49 | return self.error_class() |
| 50 | |
| 51 | def get(self, key, default=None): |
| 52 | value = super(ErrorDict, self).get(key, default) |
| 53 | if value: |
| 54 | return self.error_class(value) |
| 55 | return self.error_class() |
| 56 | |
40 | 57 | def as_ul(self): |
41 | 58 | if not self: return u'' |
42 | 59 | return mark_safe(u'<ul class="errorlist">%s</ul>' |
43 | | % ''.join([u'<li>%s</li>' % force_unicode(e) for e in self])) |
| 60 | % ''.join([u'<li>%s%s</li>' % (k, force_unicode(v)) |
| 61 | for k, v in self.items()])) |
44 | 62 | |
45 | 63 | def as_text(self): |
46 | | if not self: return u'' |
47 | | return u'\n'.join([u'* %s' % force_unicode(e) for e in self]) |
48 | | |
49 | | def __repr__(self): |
50 | | return repr([force_unicode(e) for e in self]) |
| 64 | return u'\n'.join([u'* %s\n%s' % (k, u'\n'.join([u' * %s' % force_unicode(i) for i in v])) for k, v in self.items()]) |
51 | 65 | |
52 | 66 | class ValidationError(Exception): |
53 | 67 | def __init__(self, message): |
diff --git a/django/test/_doctest.py b/django/test/_doctest.py
index a56483c..6d66a8d 100644
a
|
b
|
class DocTest:
|
503 | 503 | self.globs = globs.copy() |
504 | 504 | self.name = name |
505 | 505 | self.filename = filename |
506 | | self.lineno = lineno |
| 506 | self.lineno = lineno or 0 |
507 | 507 | |
508 | 508 | def __repr__(self): |
509 | 509 | if len(self.examples) == 0: |
diff --git a/tests/regressiontests/forms/extra.py b/tests/regressiontests/forms/extra.py
index 9dff407..2391660 100644
a
|
b
|
u'sirrobin'
|
357 | 357 | # Test overriding ErrorList in a form # |
358 | 358 | ####################################### |
359 | 359 | |
360 | | >>> from django.newforms.util import ErrorList |
| 360 | >>> from django.newforms.util import ErrorDict, ErrorList |
361 | 361 | >>> class DivErrorList(ErrorList): |
362 | 362 | ... def __unicode__(self): |
363 | 363 | ... return self.as_divs() |
364 | 364 | ... def as_divs(self): |
365 | 365 | ... if not self: return u'' |
366 | 366 | ... return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % force_unicode(e) for e in self]) |
| 367 | >>> class DivErrorDict(ErrorDict): |
| 368 | ... error_class = DivErrorList |
367 | 369 | >>> class CommentForm(Form): |
368 | 370 | ... name = CharField(max_length=50, required=False) |
369 | 371 | ... email = EmailField() |
370 | 372 | ... comment = CharField() |
371 | 373 | >>> data = dict(email='invalid') |
372 | | >>> f = CommentForm(data, auto_id=False, error_class=DivErrorList) |
| 374 | >>> f = CommentForm(data, auto_id=False, error_class=DivErrorDict) |
373 | 375 | >>> print f.as_p() |
374 | 376 | <p>Name: <input type="text" name="name" maxlength="50" /></p> |
375 | 377 | <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div> |