diff options
| author | Adrian Holovaty <adrian@holovaty.com> | 2006-12-07 06:34:37 +0000 |
|---|---|---|
| committer | Adrian Holovaty <adrian@holovaty.com> | 2006-12-07 06:34:37 +0000 |
| commit | 7e269bd390c9c4963bdce6522a8fafe6a618a5b1 (patch) | |
| tree | 343903cdec0a9a1d2e7adf66ab56aafd2a0683e4 | |
| parent | 44add112e554d9eb5a66ad4b118501a0cac9ffc1 (diff) | |
Fixed #3107 -- newforms: Added Form.as_p()
git-svn-id: http://code.djangoproject.com/svn/django/trunk@4178 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/newforms/forms.py | 27 | ||||
| -rw-r--r-- | tests/regressiontests/forms/tests.py | 52 |
2 files changed, 72 insertions, 7 deletions
diff --git a/django/newforms/forms.py b/django/newforms/forms.py index 36dd36fcce..15b24b39fe 100644 --- a/django/newforms/forms.py +++ b/django/newforms/forms.py @@ -124,6 +124,33 @@ class Form(StrAndUnicode): output.append(str_hidden) return u'\n'.join(output) + def as_p(self): + "Returns this form rendered as HTML <p>s." + top_errors = self.non_field_errors() + output, hidden_fields = [], [] + for name, field in self.fields.items(): + bf = BoundField(self, field, name) + bf_errors = bf.errors # Cache in local variable. + if bf.is_hidden: + if bf_errors: + top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors]) + hidden_fields.append(unicode(bf)) + else: + if bf_errors: + output.append(u'<p>%s</p>' % bf_errors) + output.append(u'<p>%s %s</p>' % (bf.label_tag(escape(bf.verbose_name+':')), bf)) + if top_errors: + output.insert(0, u'<p>%s</p>' % top_errors) + if hidden_fields: # Insert any hidden fields in the last <p>. + str_hidden = u''.join(hidden_fields) + if output: + last_td = output[-1] + # Chop off the trailing '</p>' and insert the hidden fields. + output[-1] = last_td[:-4] + str_hidden + '</p>' + else: # If there aren't any '<p>'s in the output, just append the hidden fields. + output.append(str_hidden) + return u'\n'.join(output) + def non_field_errors(self): """ Returns an ErrorList of errors that aren't associated with a particular diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index 16e56a8212..779db97528 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -1368,6 +1368,13 @@ False <li><ul class="errorlist"><li>This field is required.</li></ul>First name: <input type="text" name="first_name" /></li> <li><ul class="errorlist"><li>This field is required.</li></ul>Last name: <input type="text" name="last_name" /></li> <li><ul class="errorlist"><li>This field is required.</li></ul>Birthday: <input type="text" name="birthday" /></li> +>>> print p.as_p() +<p><ul class="errorlist"><li>This field is required.</li></ul></p> +<p>First name: <input type="text" name="first_name" /></p> +<p><ul class="errorlist"><li>This field is required.</li></ul></p> +<p>Last name: <input type="text" name="last_name" /></p> +<p><ul class="errorlist"><li>This field is required.</li></ul></p> +<p>Birthday: <input type="text" name="birthday" /></p> If you don't pass any values to the Form's __init__(), or if you pass None, the Form won't do any validation. Form.errors will be an empty dictionary *but* @@ -1389,6 +1396,10 @@ False <li>First name: <input type="text" name="first_name" /></li> <li>Last name: <input type="text" name="last_name" /></li> <li>Birthday: <input type="text" name="birthday" /></li> +>>> print p.as_p() +<p>First name: <input type="text" name="first_name" /></p> +<p>Last name: <input type="text" name="last_name" /></p> +<p>Birthday: <input type="text" name="birthday" /></p> Unicode values are handled properly. >>> p = Person({'first_name': u'John', 'last_name': u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111', 'birthday': '1940-10-9'}) @@ -1396,6 +1407,8 @@ Unicode values are handled properly. u'<tr><td>First name:</td><td><input type="text" name="first_name" value="John" /></td></tr>\n<tr><td>Last name:</td><td><input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /></td></tr>\n<tr><td>Birthday:</td><td><input type="text" name="birthday" value="1940-10-9" /></td></tr>' >>> p.as_ul() u'<li>First name: <input type="text" name="first_name" value="John" /></li>\n<li>Last name: <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /></li>\n<li>Birthday: <input type="text" name="birthday" value="1940-10-9" /></li>' +>>> p.as_p() +u'<p>First name: <input type="text" name="first_name" value="John" /></p>\n<p>Last name: <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /></p>\n<p>Birthday: <input type="text" name="birthday" value="1940-10-9" /></p>' >>> p = Person({'last_name': u'Lennon'}) >>> p.errors @@ -1432,14 +1445,18 @@ If it's a string that contains '%s', Django will use that as a format string into which the field's name will be inserted. It will also put a <label> around the human-readable labels for a field. >>> p = Person(auto_id='id_%s') ->>> print p.as_ul() -<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> -<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> -<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li> >>> print p.as_table() <tr><td><label for="id_first_name">First name:</label></td><td><input type="text" name="first_name" id="id_first_name" /></td></tr> <tr><td><label for="id_last_name">Last name:</label></td><td><input type="text" name="last_name" id="id_last_name" /></td></tr> <tr><td><label for="id_birthday">Birthday:</label></td><td><input type="text" name="birthday" id="id_birthday" /></td></tr> +>>> print p.as_ul() +<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> +<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> +<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></li> +>>> print p.as_p() +<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> +<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> +<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p> If auto_id is any True value whose str() does not contain '%s', the "id" attribute will be the name of the field. @@ -1596,6 +1613,12 @@ ID of the *first* radio button. <li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> </ul></li> +>>> print f.as_p() +<p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p> +<p><label for="id_language_0">Language:</label> <ul> +<li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> +<li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> +</ul></p> MultipleChoiceField is a special case, as its data is required to be a list: >>> class SongForm(Form): @@ -1754,9 +1777,9 @@ subclass' __init__(). <tr><td>Last name:</td><td><input type="text" name="last_name" /></td></tr> <tr><td>Birthday:</td><td><input type="text" name="birthday" /></td></tr> -HiddenInput widgets are displayed differently in the as_table() and as_ul() -output of a Form -- their verbose names are not displayed, and a separate -<tr>/<li> is not displayed. They're displayed in the last <td>/<li> of the +HiddenInput widgets are displayed differently in the as_table(), as_ul() +and as_p() output of a Form -- their verbose names are not displayed, and a +separate row is not displayed. They're displayed in the last row of the form, directly after that row's form element. >>> class Person(Form): ... first_name = CharField() @@ -1772,6 +1795,10 @@ form, directly after that row's form element. <li>First name: <input type="text" name="first_name" /></li> <li>Last name: <input type="text" name="last_name" /></li> <li>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></li> +>>> print p.as_p() +<p>First name: <input type="text" name="first_name" /></p> +<p>Last name: <input type="text" name="last_name" /></p> +<p>Birthday: <input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></p> With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label. >>> p = Person(auto_id='id_%s') @@ -1783,6 +1810,10 @@ With auto_id set, a HiddenInput still gets an ID, but it doesn't get a label. <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li> <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li> <li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></li> +>>> print p.as_p() +<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> +<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> +<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></p> If a field with a HiddenInput has errors, the as_table() and as_ul() output will include the error message(s) with the text "(Hidden field [fieldname]) " @@ -1799,6 +1830,11 @@ its field's order in the form. <li>First name: <input type="text" name="first_name" value="John" /></li> <li>Last name: <input type="text" name="last_name" value="Lennon" /></li> <li>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></li> +>>> print p.as_p() +<p><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></p> +<p>First name: <input type="text" name="first_name" value="John" /></p> +<p>Last name: <input type="text" name="last_name" value="Lennon" /></p> +<p>Birthday: <input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></p> A corner case: It's possible for a form to have only HiddenInputs. >>> class TestForm(Form): @@ -1809,6 +1845,8 @@ A corner case: It's possible for a form to have only HiddenInputs. <input type="hidden" name="foo" /><input type="hidden" name="bar" /> >>> print p.as_ul() <input type="hidden" name="foo" /><input type="hidden" name="bar" /> +>>> print p.as_p() +<input type="hidden" name="foo" /><input type="hidden" name="bar" /> A Form's fields are displayed in the same order in which they were defined. >>> class TestForm(Form): |
