Ticket #3255: newforms-help_text.diff
File newforms-help_text.diff, 39.2 KB (added by , 18 years ago) |
---|
-
django/newforms/fields.py
33 33 # Tracks each time a Field instance is created. Used to retain order. 34 34 creation_counter = 0 35 35 36 def __init__(self, required=True, widget=None, label=None, initial=None ):36 def __init__(self, required=True, widget=None, label=None, initial=None, help_text=None): 37 37 # required -- Boolean that specifies whether the field is required. 38 38 # True by default. 39 39 # widget -- A Widget class, or instance of a Widget class, that should be … … 47 47 # *not* used as a fallback if data isn't given. 48 48 if label is not None: 49 49 label = smart_unicode(label) 50 self.required, self.label, self.initial = required, label, initial50 self.required, self.label, self.initial, self.help_text = required, label, initial, help_text 51 51 widget = widget or self.widget 52 52 if isinstance(widget, type): 53 53 widget = widget() … … 83 83 return {} 84 84 85 85 class CharField(Field): 86 def __init__(self, max_length=None, min_length=None, required=True, widget=None, label=None, initial=None ):86 def __init__(self, max_length=None, min_length=None, required=True, widget=None, label=None, initial=None, help_text=None): 87 87 self.max_length, self.min_length = max_length, min_length 88 Field.__init__(self, required, widget, label, initial )88 Field.__init__(self, required, widget, label, initial, help_text) 89 89 90 90 def clean(self, value): 91 91 "Validates max_length and min_length. Returns a Unicode object." … … 106 106 return {'maxlength': str(self.max_length)} 107 107 108 108 class IntegerField(Field): 109 def __init__(self, max_value=None, min_value=None, required=True, widget=None, label=None, initial=None ):109 def __init__(self, max_value=None, min_value=None, required=True, widget=None, label=None, initial=None, help_text=None): 110 110 self.max_value, self.min_value = max_value, min_value 111 Field.__init__(self, required, widget, label, initial )111 Field.__init__(self, required, widget, label, initial, help_text) 112 112 113 113 def clean(self, value): 114 114 """ … … 137 137 ) 138 138 139 139 class DateField(Field): 140 def __init__(self, input_formats=None, required=True, widget=None, label=None, initial=None ):141 Field.__init__(self, required, widget, label, initial )140 def __init__(self, input_formats=None, required=True, widget=None, label=None, initial=None, help_text=None): 141 Field.__init__(self, required, widget, label, initial, help_text) 142 142 self.input_formats = input_formats or DEFAULT_DATE_INPUT_FORMATS 143 143 144 144 def clean(self, value): … … 166 166 ) 167 167 168 168 class TimeField(Field): 169 def __init__(self, input_formats=None, required=True, widget=None, label=None, initial=None ):170 Field.__init__(self, required, widget, label, initial )169 def __init__(self, input_formats=None, required=True, widget=None, label=None, initial=None, help_text=None): 170 Field.__init__(self, required, widget, label, initial, help_text) 171 171 self.input_formats = input_formats or DEFAULT_TIME_INPUT_FORMATS 172 172 173 173 def clean(self, value): … … 200 200 ) 201 201 202 202 class DateTimeField(Field): 203 def __init__(self, input_formats=None, required=True, widget=None, label=None, initial=None ):204 Field.__init__(self, required, widget, label, initial )203 def __init__(self, input_formats=None, required=True, widget=None, label=None, initial=None, help_text=None): 204 Field.__init__(self, required, widget, label, initial, help_text) 205 205 self.input_formats = input_formats or DEFAULT_DATETIME_INPUT_FORMATS 206 206 207 207 def clean(self, value): … … 225 225 226 226 class RegexField(Field): 227 227 def __init__(self, regex, max_length=None, min_length=None, error_message=None, 228 required=True, widget=None, label=None, initial=None ):228 required=True, widget=None, label=None, initial=None, help_text=None): 229 229 """ 230 230 regex can be either a string or a compiled regular expression object. 231 231 error_message is an optional error message to use, if … … 262 262 r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE) # domain 263 263 264 264 class EmailField(RegexField): 265 def __init__(self, max_length=None, min_length=None, required=True, widget=None, label=None, initial=None ):266 RegexField.__init__(self, email_re, max_length, min_length, gettext(u'Enter a valid e-mail address.'), required, widget, label, initial )265 def __init__(self, max_length=None, min_length=None, required=True, widget=None, label=None, initial=None, help_text=None): 266 RegexField.__init__(self, email_re, max_length, min_length, gettext(u'Enter a valid e-mail address.'), required, widget, label, initial, help_text) 267 267 268 268 url_re = re.compile( 269 269 r'^https?://' # http:// or https:// … … 280 280 281 281 class URLField(RegexField): 282 282 def __init__(self, max_length=None, min_length=None, required=True, verify_exists=False, widget=None, label=None, 283 initial=None, validator_user_agent=URL_VALIDATOR_USER_AGENT ):284 RegexField.__init__(self, url_re, max_length, min_length, gettext(u'Enter a valid URL.'), required, widget, label, initial )283 initial=None, validator_user_agent=URL_VALIDATOR_USER_AGENT, help_text=None): 284 RegexField.__init__(self, url_re, max_length, min_length, gettext(u'Enter a valid URL.'), required, widget, label, initial, help_text) 285 285 self.verify_exists = verify_exists 286 286 self.user_agent = validator_user_agent 287 287 … … 315 315 return bool(value) 316 316 317 317 class ChoiceField(Field): 318 def __init__(self, choices=(), required=True, widget=Select, label=None, initial=None ):318 def __init__(self, choices=(), required=True, widget=Select, label=None, initial=None, help_text=None): 319 319 if isinstance(widget, type): 320 320 widget = widget(choices=choices) 321 Field.__init__(self, required, widget, label, initial )321 Field.__init__(self, required, widget, label, initial, help_text) 322 322 self.choices = choices 323 323 324 324 def clean(self, value): … … 336 336 return value 337 337 338 338 class MultipleChoiceField(ChoiceField): 339 def __init__(self, choices=(), required=True, widget=SelectMultiple, label=None, initial=None ):340 ChoiceField.__init__(self, choices, required, widget, label, initial )339 def __init__(self, choices=(), required=True, widget=SelectMultiple, label=None, initial=None, help_text=None): 340 ChoiceField.__init__(self, choices, required, widget, label, initial, help_text) 341 341 342 342 def clean(self, value): 343 343 """ … … 361 361 return new_value 362 362 363 363 class ComboField(Field): 364 def __init__(self, fields=(), required=True, widget=None, label=None, initial=None ):365 Field.__init__(self, required, widget, label, initial )364 def __init__(self, fields=(), required=True, widget=None, label=None, initial=None, help_text=None): 365 Field.__init__(self, required, widget, label, initial, help_text) 366 366 # Set 'required' to False on the individual fields, because the 367 367 # required validation will be handled by ComboField, not by those 368 368 # individual fields. -
django/newforms/forms.py
84 84 """ 85 85 return self.prefix and ('%s-%s' % (self.prefix, field_name)) or field_name 86 86 87 def _html_output(self, normal_row, error_row, row_ender, errors_on_separate_row):87 def _html_output(self, normal_row, error_row, help_row, row_ender, errors_on_separate_row, help_on_separate_row): 88 88 "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." 89 89 top_errors = self.non_field_errors() # Errors that should be displayed above all fields. 90 90 output, hidden_fields = [], [] 91 91 for name, field in self.fields.items(): 92 92 bf = BoundField(self, field, name) 93 93 bf_errors = bf.errors # Cache in local variable. 94 bf_help_text = bf.field.help_text or '' 94 95 if bf.is_hidden: 95 96 if bf_errors: 96 97 top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors]) … … 99 100 if errors_on_separate_row and bf_errors: 100 101 output.append(error_row % bf_errors) 101 102 label = bf.label and bf.label_tag(escape(bf.label + ':')) or '' 102 output.append(normal_row % {'errors': bf_errors, 'label': label, 'field': bf}) 103 output.append(normal_row % {'errors': bf_errors, 'label': label, 'field': bf, 'help_text': bf_help_text}) 104 if help_on_separate_row and bf_help_text: 105 output.append(help_row % bf_help_text) 103 106 if top_errors: 104 107 output.insert(0, error_row % top_errors) 105 108 if hidden_fields: # Insert any hidden fields in the last row. … … 114 117 115 118 def as_table(self): 116 119 "Returns this form rendered as HTML <tr>s -- excluding the <table></table>." 117 return self._html_output(u'<tr><th>%(label)s</th><td>%(errors)s%(field)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', False) 120 return self._html_output(u'<tr><th>%(label)s</th><td>%(errors)s%(field)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', 121 u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', False, True) 118 122 119 123 def as_ul(self): 120 124 "Returns this form rendered as HTML <li>s -- excluding the <ul></ul>." 121 return self._html_output(u'<li>%(errors)s%(label)s %(field)s </li>', u'<li>%s</li>', '</li>', False)125 return self._html_output(u'<li>%(errors)s%(label)s %(field)s %(help_text)s</li>', u'<li>%s</li>', u'<li>%s</li>', '</li>', False, False) 122 126 123 127 def as_p(self): 124 128 "Returns this form rendered as HTML <p>s." 125 return self._html_output(u'<p>%(label)s %(field)s</p>', u'<p>%s</p>', '</p>', True)129 return self._html_output(u'<p>%(label)s %(field)s</p>', u'<p>%s</p>', u'<p>%s</p>', '</p>', True, True) 126 130 127 131 def non_field_errors(self): 128 132 """ -
tests/modeltests/model_forms/models.py
56 56 <tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr> 57 57 <tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr> 58 58 >>> print f.as_ul() 59 <li><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" maxlength="20" /> </li>60 <li><label for="id_url">The URL:</label> <input id="id_url" type="text" name="url" maxlength="40" /> </li>59 <li><label for="id_name">Name:</label> <input id="id_name" type="text" name="name" maxlength="20" /> </li> 60 <li><label for="id_url">The URL:</label> <input id="id_url" type="text" name="url" maxlength="40" /> </li> 61 61 >>> print f['name'] 62 62 <input id="id_name" type="text" name="name" maxlength="20" /> 63 63 64 64 >>> f = CategoryForm(auto_id=False) 65 65 >>> print f.as_ul() 66 <li>Name: <input type="text" name="name" maxlength="20" /> </li>67 <li>The URL: <input type="text" name="url" maxlength="40" /> </li>66 <li>Name: <input type="text" name="name" maxlength="20" /> </li> 67 <li>The URL: <input type="text" name="url" maxlength="40" /> </li> 68 68 69 69 >>> f = CategoryForm({'name': 'Entertainment', 'url': 'entertainment'}) 70 70 >>> f.is_valid() … … 173 173 >>> TestArticleForm = form_for_instance(art) 174 174 >>> f = TestArticleForm(auto_id=False) 175 175 >>> print f.as_ul() 176 <li>Headline: <input type="text" name="headline" value="Test article" maxlength="50" /> </li>177 <li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /> </li>176 <li>Headline: <input type="text" name="headline" value="Test article" maxlength="50" /> </li> 177 <li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /> </li> 178 178 <li>Writer: <select name="writer"> 179 179 <option value="">---------</option> 180 180 <option value="1" selected="selected">Mike Royko</option> 181 181 <option value="2">Bob Woodward</option> 182 </select> </li>182 </select> </li> 183 183 <li>Categories: <select multiple="multiple" name="categories"> 184 184 <option value="1">Entertainment</option> 185 185 <option value="2">It's a test</option> 186 186 <option value="3">Third test</option> 187 </select> </li>187 </select> </li> 188 188 >>> f = TestArticleForm({'headline': u'New headline', 'pub_date': u'1988-01-04', 'writer': u'1'}) 189 189 >>> f.is_valid() 190 190 True … … 204 204 >>> TestArticleForm = form_for_instance(new_art) 205 205 >>> f = TestArticleForm(auto_id=False) 206 206 >>> print f.as_ul() 207 <li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /> </li>208 <li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /> </li>207 <li>Headline: <input type="text" name="headline" value="New headline" maxlength="50" /> </li> 208 <li>Pub date: <input type="text" name="pub_date" value="1988-01-04" /> </li> 209 209 <li>Writer: <select name="writer"> 210 210 <option value="">---------</option> 211 211 <option value="1" selected="selected">Mike Royko</option> 212 212 <option value="2">Bob Woodward</option> 213 </select> </li>213 </select> </li> 214 214 <li>Categories: <select multiple="multiple" name="categories"> 215 215 <option value="1" selected="selected">Entertainment</option> 216 216 <option value="2">It's a test</option> 217 217 <option value="3">Third test</option> 218 </select> </li>218 </select> </li> 219 219 220 220 """} -
tests/regressiontests/forms/tests.py
1561 1561 <tr><th><label for="id_last_name">Last name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="last_name" id="id_last_name" /></td></tr> 1562 1562 <tr><th><label for="id_birthday">Birthday:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="birthday" id="id_birthday" /></td></tr> 1563 1563 >>> print p.as_ul() 1564 <li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /> </li>1565 <li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /> </li>1566 <li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /> </li>1564 <li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /> </li> 1565 <li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /> </li> 1566 <li><ul class="errorlist"><li>This field is required.</li></ul><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /> </li> 1567 1567 >>> print p.as_p() 1568 1568 <p><ul class="errorlist"><li>This field is required.</li></ul></p> 1569 1569 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> … … 1595 1595 <tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr> 1596 1596 <tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr> 1597 1597 >>> print p.as_ul() 1598 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /> </li>1599 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /> </li>1600 <li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /> </li>1598 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /> </li> 1599 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /> </li> 1600 <li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /> </li> 1601 1601 >>> print p.as_p() 1602 1602 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> 1603 1603 <p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> … … 1608 1608 >>> p.as_table() 1609 1609 u'<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>\n<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></td></tr>\n<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>' 1610 1610 >>> p.as_ul() 1611 u'<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /> </li>\n<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></li>\n<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></li>'1611 u'<li><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /> </li>\n<li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /> </li>\n<li><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /> </li>' 1612 1612 >>> p.as_p() 1613 1613 u'<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></p>\n<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" /></p>\n<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></p>' 1614 1614 … … 1653 1653 <tr><th><label for="last_name_id">Last name:</label></th><td><input type="text" name="last_name" id="last_name_id" /></td></tr> 1654 1654 <tr><th><label for="birthday_id">Birthday:</label></th><td><input type="text" name="birthday" id="birthday_id" /></td></tr> 1655 1655 >>> print p.as_ul() 1656 <li><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /> </li>1657 <li><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /> </li>1658 <li><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /> </li>1656 <li><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /> </li> 1657 <li><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /> </li> 1658 <li><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /> </li> 1659 1659 >>> print p.as_p() 1660 1660 <p><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></p> 1661 1661 <p><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></p> … … 1665 1665 attribute will be the name of the field. 1666 1666 >>> p = Person(auto_id=True) 1667 1667 >>> print p.as_ul() 1668 <li><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /> </li>1669 <li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /> </li>1670 <li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /> </li>1668 <li><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /> </li> 1669 <li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /> </li> 1670 <li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /> </li> 1671 1671 1672 1672 If auto_id is any False value, an "id" attribute won't be output unless it 1673 1673 was manually entered. 1674 1674 >>> p = Person(auto_id=False) 1675 1675 >>> print p.as_ul() 1676 <li>First name: <input type="text" name="first_name" /> </li>1677 <li>Last name: <input type="text" name="last_name" /> </li>1678 <li>Birthday: <input type="text" name="birthday" /> </li>1676 <li>First name: <input type="text" name="first_name" /> </li> 1677 <li>Last name: <input type="text" name="last_name" /> </li> 1678 <li>Birthday: <input type="text" name="birthday" /> </li> 1679 1679 1680 1680 In this example, auto_id is False, but the "id" attribute for the "first_name" 1681 1681 field is given. Also note that field gets a <label>, while the others don't. … … 1685 1685 ... birthday = DateField() 1686 1686 >>> p = PersonNew(auto_id=False) 1687 1687 >>> print p.as_ul() 1688 <li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /> </li>1689 <li>Last name: <input type="text" name="last_name" /> </li>1690 <li>Birthday: <input type="text" name="birthday" /> </li>1688 <li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /> </li> 1689 <li>Last name: <input type="text" name="last_name" /> </li> 1690 <li>Birthday: <input type="text" name="birthday" /> </li> 1691 1691 1692 1692 If the "id" attribute is specified in the Form and auto_id is True, the "id" 1693 1693 attribute in the Form gets precedence. 1694 1694 >>> p = PersonNew(auto_id=True) 1695 1695 >>> print p.as_ul() 1696 <li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /> </li>1697 <li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /> </li>1698 <li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /> </li>1696 <li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /> </li> 1697 <li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /> </li> 1698 <li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /> </li> 1699 1699 1700 1700 >>> class SignupForm(Form): 1701 1701 ... email = EmailField() … … 1785 1785 <li><label><input type="radio" name="language" value="J" /> Java</label></li> 1786 1786 </ul></td></tr> 1787 1787 >>> print f.as_ul() 1788 <li>Name: <input type="text" name="name" /> </li>1788 <li>Name: <input type="text" name="name" /> </li> 1789 1789 <li>Language: <ul> 1790 1790 <li><label><input type="radio" name="language" value="P" /> Python</label></li> 1791 1791 <li><label><input type="radio" name="language" value="J" /> Java</label></li> 1792 </ul> </li>1792 </ul> </li> 1793 1793 1794 1794 Regarding auto_id and <label>, RadioSelect is a special case. Each radio button 1795 1795 gets a distinct ID, formed by appending an underscore plus the button's … … 1811 1811 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> 1812 1812 </ul></td></tr> 1813 1813 >>> print f.as_ul() 1814 <li><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /> </li>1814 <li><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /> </li> 1815 1815 <li><label for="id_language_0">Language:</label> <ul> 1816 1816 <li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li> 1817 1817 <li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li> 1818 </ul> </li>1818 </ul> </li> 1819 1819 >>> print f.as_p() 1820 1820 <p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p> 1821 1821 <p><label for="id_language_0">Language:</label> <ul> … … 1970 1970 <tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr> 1971 1971 >>> print f.as_ul() 1972 1972 <li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li> 1973 <li>Username: <input type="text" name="username" value="adrian" maxlength="10" /> </li>1974 <li>Password1: <input type="password" name="password1" value="foo" /> </li>1975 <li>Password2: <input type="password" name="password2" value="bar" /> </li>1973 <li>Username: <input type="text" name="username" value="adrian" maxlength="10" /> </li> 1974 <li>Password1: <input type="password" name="password1" value="foo" /> </li> 1975 <li>Password2: <input type="password" name="password2" value="bar" /> </li> 1976 1976 >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False) 1977 1977 >>> f.errors 1978 1978 {} … … 2009 2009 <tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr> 2010 2010 <tr><th>Birthday:</th><td><input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></td></tr> 2011 2011 >>> print p.as_ul() 2012 <li>First name: <input type="text" name="first_name" /> </li>2013 <li>Last name: <input type="text" name="last_name" /> </li>2014 <li>Birthday: <input type="text" name="birthday" /> <input type="hidden" name="hidden_text" /></li>2012 <li>First name: <input type="text" name="first_name" /> </li> 2013 <li>Last name: <input type="text" name="last_name" /> </li> 2014 <li>Birthday: <input type="text" name="birthday" /> <input type="hidden" name="hidden_text" /></li> 2015 2015 >>> print p.as_p() 2016 2016 <p>First name: <input type="text" name="first_name" /></p> 2017 2017 <p>Last name: <input type="text" name="last_name" /></p> … … 2024 2024 <tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr> 2025 2025 <tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></td></tr> 2026 2026 >>> print p.as_ul() 2027 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /> </li>2028 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /> </li>2029 <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>2027 <li><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /> </li> 2028 <li><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /> </li> 2029 <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> 2030 2030 >>> print p.as_p() 2031 2031 <p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p> 2032 2032 <p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p> … … 2044 2044 <tr><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr> 2045 2045 >>> print p.as_ul() 2046 2046 <li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li> 2047 <li>First name: <input type="text" name="first_name" value="John" /> </li>2048 <li>Last name: <input type="text" name="last_name" value="Lennon" /> </li>2049 <li>Birthday: <input type="text" name="birthday" value="1940-10-9" /> <input type="hidden" name="hidden_text" /></li>2047 <li>First name: <input type="text" name="first_name" value="John" /> </li> 2048 <li>Last name: <input type="text" name="last_name" value="Lennon" /> </li> 2049 <li>Birthday: <input type="text" name="birthday" value="1940-10-9" /> <input type="hidden" name="hidden_text" /></li> 2050 2050 >>> print p.as_p() 2051 2051 <p><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></p> 2052 2052 <p>First name: <input type="text" name="first_name" value="John" /></p> … … 2109 2109 ... address = CharField() # no max_length defined here 2110 2110 >>> p = UserRegistration(auto_id=False) 2111 2111 >>> print p.as_ul() 2112 <li>Username: <input type="text" name="username" maxlength="10" /> </li>2113 <li>Password: <input type="password" name="password" maxlength="10" /> </li>2114 <li>Realname: <input type="text" name="realname" maxlength="10" /> </li>2115 <li>Address: <input type="text" name="address" /> </li>2112 <li>Username: <input type="text" name="username" maxlength="10" /> </li> 2113 <li>Password: <input type="password" name="password" maxlength="10" /> </li> 2114 <li>Realname: <input type="text" name="realname" maxlength="10" /> </li> 2115 <li>Address: <input type="text" name="address" /> </li> 2116 2116 2117 2117 If you specify a custom "attrs" that includes the "maxlength" attribute, 2118 2118 the Field's max_length attribute will override whatever "maxlength" you specify … … 2122 2122 ... password = CharField(max_length=10, widget=PasswordInput) 2123 2123 >>> p = UserRegistration(auto_id=False) 2124 2124 >>> print p.as_ul() 2125 <li>Username: <input type="text" name="username" maxlength="10" /> </li>2126 <li>Password: <input type="password" name="password" maxlength="10" /> </li>2125 <li>Username: <input type="text" name="username" maxlength="10" /> </li> 2126 <li>Password: <input type="password" name="password" maxlength="10" /> </li> 2127 2127 2128 2128 # Specifying labels ########################################################### 2129 2129 … … 2136 2136 ... password2 = CharField(widget=PasswordInput, label='Password (again)') 2137 2137 >>> p = UserRegistration(auto_id=False) 2138 2138 >>> print p.as_ul() 2139 <li>Your username: <input type="text" name="username" maxlength="10" /> </li>2140 <li>Password1: <input type="password" name="password1" /> </li>2141 <li>Password (again): <input type="password" name="password2" /> </li>2139 <li>Your username: <input type="text" name="username" maxlength="10" /> </li> 2140 <li>Password1: <input type="password" name="password1" /> </li> 2141 <li>Password (again): <input type="password" name="password2" /> </li> 2142 2142 2143 2143 A label can be a Unicode object or a bytestring with special characters. 2144 2144 >>> class UserRegistration(Form): … … 2146 2146 ... password = CharField(widget=PasswordInput, label=u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') 2147 2147 >>> p = UserRegistration(auto_id=False) 2148 2148 >>> p.as_ul() 2149 u'<li>\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="text" name="username" maxlength="10" /> </li>\n<li>\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="password" name="password" /></li>'2149 u'<li>\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="text" name="username" maxlength="10" /> </li>\n<li>\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="password" name="password" /> </li>' 2150 2150 2151 2151 If a label is set to the empty string for a field, that field won't get a label. 2152 2152 >>> class UserRegistration(Form): … … 2154 2154 ... password = CharField(widget=PasswordInput) 2155 2155 >>> p = UserRegistration(auto_id=False) 2156 2156 >>> print p.as_ul() 2157 <li> <input type="text" name="username" maxlength="10" /> </li>2158 <li>Password: <input type="password" name="password" /> </li>2157 <li> <input type="text" name="username" maxlength="10" /> </li> 2158 <li>Password: <input type="password" name="password" /> </li> 2159 2159 >>> p = UserRegistration(auto_id='id_%s') 2160 2160 >>> print p.as_ul() 2161 <li> <input id="id_username" type="text" name="username" maxlength="10" /> </li>2162 <li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /> </li>2161 <li> <input id="id_username" type="text" name="username" maxlength="10" /> </li> 2162 <li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /> </li> 2163 2163 2164 2164 If label is None, Django will auto-create the label from the field name. This 2165 2165 is default behavior. … … 2168 2168 ... password = CharField(widget=PasswordInput) 2169 2169 >>> p = UserRegistration(auto_id=False) 2170 2170 >>> print p.as_ul() 2171 <li>Username: <input type="text" name="username" maxlength="10" /> </li>2172 <li>Password: <input type="password" name="password" /> </li>2171 <li>Username: <input type="text" name="username" maxlength="10" /> </li> 2172 <li>Password: <input type="password" name="password" /> </li> 2173 2173 >>> p = UserRegistration(auto_id='id_%s') 2174 2174 >>> print p.as_ul() 2175 <li><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="10" /> </li>2176 <li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /> </li>2175 <li><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="10" /> </li> 2176 <li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /> </li> 2177 2177 2178 2178 # Initial data ################################################################ 2179 2179 … … 2189 2189 Here, we're not submitting any data, so the initial value will be displayed. 2190 2190 >>> p = UserRegistration(auto_id=False) 2191 2191 >>> print p.as_ul() 2192 <li>Username: <input type="text" name="username" value="django" maxlength="10" /> </li>2193 <li>Password: <input type="password" name="password" /> </li>2192 <li>Username: <input type="text" name="username" value="django" maxlength="10" /> </li> 2193 <li>Password: <input type="password" name="password" /> </li> 2194 2194 2195 2195 Here, we're submitting data, so the initial value will *not* be displayed. 2196 2196 >>> p = UserRegistration({}, auto_id=False) 2197 2197 >>> print p.as_ul() 2198 <li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /> </li>2199 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> </li>2198 <li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /> </li> 2199 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> </li> 2200 2200 >>> p = UserRegistration({'username': u''}, auto_id=False) 2201 2201 >>> print p.as_ul() 2202 <li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /> </li>2203 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> </li>2202 <li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /> </li> 2203 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> </li> 2204 2204 >>> p = UserRegistration({'username': u'foo'}, auto_id=False) 2205 2205 >>> print p.as_ul() 2206 <li>Username: <input type="text" name="username" value="foo" maxlength="10" /> </li>2207 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> </li>2206 <li>Username: <input type="text" name="username" value="foo" maxlength="10" /> </li> 2207 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> </li> 2208 2208 2209 2209 An 'initial' value is *not* used as a fallback if data is not provided. In this 2210 2210 example, we don't provide a value for 'username', and the form raises a … … 2215 2215 >>> p.is_valid() 2216 2216 False 2217 2217 2218 # Help text ################################################################### 2219 2220 You can specify descriptive text for a field by using the 'help_text' argument 2221 to a Field class. This help text is displayed when a Form is rendered. 2222 >>> class UserRegistration(Form): 2223 ... username = CharField(max_length=10, help_text='Ex. user@example.com') 2224 ... password = CharField(widget=PasswordInput) 2225 2226 Help text is presented verbatim in all as_*() methods. 2227 >>> p = UserRegistration(auto_id=False) 2228 >>> print p.as_ul() 2229 <li>Username: <input type="text" name="username" maxlength="10" /> Ex. user@example.com</li> 2230 <li>Password: <input type="password" name="password" /> </li> 2231 >>> print p.as_p() 2232 <p>Username: <input type="text" name="username" maxlength="10" /></p> 2233 <p>Ex. user@example.com</p> 2234 <p>Password: <input type="password" name="password" /></p> 2235 >>> print p.as_table() 2236 <tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /></td></tr> 2237 <tr><td colspan="2">Ex. user@example.com</td></tr> 2238 <tr><th>Password:</th><td><input type="password" name="password" /></td></tr> 2239 2240 The help text is displayed wheter or not data is provided for the form. 2241 >>> p = UserRegistration({'username': u'foo'}, auto_id=False) 2242 >>> print p.as_ul() 2243 <li>Username: <input type="text" name="username" value="foo" maxlength="10" /> Ex. user@example.com</li> 2244 <li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> </li> 2245 2246 For hidden fields, help_text is not displayed. It can be used for documentation purposes though. 2247 >>> class UserRegistration(Form): 2248 ... username = CharField(max_length=10, help_text='Ex. user@example.com') 2249 ... password = CharField(widget=PasswordInput) 2250 ... next = CharField(widget=HiddenInput, initial='/', help_text='Redirect to destination') 2251 >>> p = UserRegistration(auto_id=False) 2252 >>> print p.as_ul() 2253 <li>Username: <input type="text" name="username" maxlength="10" /> Ex. user@example.com</li> 2254 <li>Password: <input type="password" name="password" /> <input type="hidden" name="next" value="/" /></li> 2255 2218 2256 # Forms with prefixes ######################################################### 2219 2257 2220 2258 Sometimes it's necessary to have multiple forms display on the same HTML page, … … 2235 2273 ... } 2236 2274 >>> p = Person(data, prefix='person1') 2237 2275 >>> print p.as_ul() 2238 <li><label for="id_person1-first_name">First name:</label> <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" /> </li>2239 <li><label for="id_person1-last_name">Last name:</label> <input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" /> </li>2240 <li><label for="id_person1-birthday">Birthday:</label> <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /> </li>2276 <li><label for="id_person1-first_name">First name:</label> <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" /> </li> 2277 <li><label for="id_person1-last_name">Last name:</label> <input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" /> </li> 2278 <li><label for="id_person1-birthday">Birthday:</label> <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /> </li> 2241 2279 >>> print p['first_name'] 2242 2280 <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" /> 2243 2281 >>> print p['last_name'] … … 2312 2350 ... return self.prefix and '%s-prefix-%s' % (self.prefix, field_name) or field_name 2313 2351 >>> p = Person(prefix='foo') 2314 2352 >>> print p.as_ul() 2315 <li><label for="id_foo-prefix-first_name">First name:</label> <input type="text" name="foo-prefix-first_name" id="id_foo-prefix-first_name" /> </li>2316 <li><label for="id_foo-prefix-last_name">Last name:</label> <input type="text" name="foo-prefix-last_name" id="id_foo-prefix-last_name" /> </li>2317 <li><label for="id_foo-prefix-birthday">Birthday:</label> <input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" /> </li>2353 <li><label for="id_foo-prefix-first_name">First name:</label> <input type="text" name="foo-prefix-first_name" id="id_foo-prefix-first_name" /> </li> 2354 <li><label for="id_foo-prefix-last_name">Last name:</label> <input type="text" name="foo-prefix-last_name" id="id_foo-prefix-last_name" /> </li> 2355 <li><label for="id_foo-prefix-birthday">Birthday:</label> <input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" /> </li> 2318 2356 >>> data = { 2319 2357 ... 'foo-prefix-first_name': u'John', 2320 2358 ... 'foo-prefix-last_name': u'Lennon',