Index: django/newforms/forms.py
===================================================================
--- django/newforms/forms.py	(revision 4732)
+++ django/newforms/forms.py	(working copy)
@@ -107,10 +107,11 @@
         """
         return self.prefix and ('%s-%s' % (self.prefix, field_name)) or field_name
 
-    def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row):
+    def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row, html_class_list=None):
         "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()."
         top_errors = self.non_field_errors() # Errors that should be displayed above all fields.
         output, hidden_fields = [], []
+        html_class_list = html_class_list or []
         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.
@@ -119,6 +120,15 @@
                     top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors])
                 hidden_fields.append(unicode(bf))
             else:
+                class_list = list(html_class_list) # A fresh list for each loop.
+                if bf_errors:
+                    class_list.append('error')
+                if bf.field.required:
+                    class_list.append('required')
+                if class_list:
+                    html_class = ' class="%s"' % ' '.join(class_list)
+                else:
+                    html_class = ''
                 if errors_on_separate_row and bf_errors:
                     output.append(error_row % bf_errors)
                 label = bf.label and bf.label_tag(escape(bf.label + ':')) or ''
@@ -126,7 +136,7 @@
                     help_text = help_text_html % field.help_text
                 else:
                     help_text = u''
-                output.append(normal_row % {'errors': bf_errors, 'label': label, 'field': unicode(bf), 'help_text': help_text})
+                output.append(normal_row % {'errors': bf_errors, 'label': label, 'field': unicode(bf), 'help_text': help_text, 'html_class': html_class})
         if top_errors:
             output.insert(0, error_row % top_errors)
         if hidden_fields: # Insert any hidden fields in the last row.
@@ -141,15 +151,15 @@
 
     def as_table(self):
         "Returns this form rendered as HTML <tr>s -- excluding the <table></table>."
-        return self._html_output(u'<tr><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', u'<br />%s', False)
+        return self._html_output(u'<tr%(html_class)s><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', u'<br />%s', False)
 
     def as_ul(self):
         "Returns this form rendered as HTML <li>s -- excluding the <ul></ul>."
-        return self._html_output(u'<li>%(errors)s%(label)s %(field)s%(help_text)s</li>', u'<li>%s</li>', '</li>', u' %s', False)
+        return self._html_output(u'<li%(html_class)s>%(errors)s%(label)s %(field)s%(help_text)s</li>', u'<li>%s</li>', '</li>', u' %s', False)
 
     def as_p(self):
         "Returns this form rendered as HTML <p>s."
-        return self._html_output(u'<p>%(label)s %(field)s%(help_text)s</p>', u'<p>%s</p>', '</p>', u' %s', True)
+        return self._html_output(u'<p%(html_class)s>%(label)s %(field)s%(help_text)s</p>', u'<p>%s</p>', '</p>', u' %s', True)
 
     def non_field_errors(self):
         """
Index: docs/newforms.txt
===================================================================
--- docs/newforms.txt	(revision 4732)
+++ docs/newforms.txt	(working copy)
@@ -293,10 +293,10 @@
 
     >>> f = ContactForm()
     >>> print f
-    <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
-    <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
-    <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
+    <tr class="required"><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
+    <tr class="required"><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
+    <tr class="required"><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
+    <tr class="required"><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
 
 If the form is bound to data, the HTML output will include that data
 appropriately. For example, if a field is represented by an
@@ -310,10 +310,10 @@
     ...         'cc_myself': True}
     >>> f = ContactForm(data)
     >>> print f
-    <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" value="hello" /></td></tr>
-    <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" value="Hi there" /></td></tr>
-    <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" value="foo@example.com" /></td></tr>
-    <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" checked="checked" /></td></tr>
+    <tr class="required"><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" value="hello" /></td></tr>
+    <tr class="required"><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" value="Hi there" /></td></tr>
+    <tr class="required"><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" value="foo@example.com" /></td></tr>
+    <tr class="required"><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" checked="checked" /></td></tr>
 
 This default output is a two-column HTML table, with a ``<tr>`` for each field.
 Notice the following:
@@ -354,12 +354,12 @@
 
     >>> f = ContactForm()
     >>> f.as_p()
-    u'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
+    u'<p class="required"><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p class="required"><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p class="required"><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p class="required"><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
     >>> print f.as_p()
-    <p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
-    <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
-    <p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>
-    <p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
+    <p class="required"><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
+    <p class="required"><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
+    <p class="required"><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>
+    <p class="required"><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
 
 ``as_ul()``
 ~~~~~~~~~~~
@@ -370,12 +370,12 @@
 
     >>> f = ContactForm()
     >>> f.as_ul()
-    u'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
+    u'<li class="required"><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li class="required"><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li class="required"><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li class="required"><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
     >>> print f.as_ul()
-    <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
-    <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
-    <li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
-    <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
+    <li class="required"><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
+    <li class="required"><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
+    <li class="required"><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
+    <li class="required"><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
 
 ``as_table()``
 ~~~~~~~~~~~~~~
@@ -386,12 +386,12 @@
 
     >>> f = ContactForm()
     >>> f.as_table()
-    u'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
+    u'<tr class="required"><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr class="required"><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr class="required"><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr class="required"><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
     >>> print f.as_table()
-    <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
-    <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
-    <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
+    <tr class="required"><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
+    <tr class="required"><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
+    <tr class="required"><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
+    <tr class="required"><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
 
 Configuring HTML ``<label>`` tags
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -414,20 +414,20 @@
 
     >>> f = ContactForm(auto_id=False)
     >>> print f.as_table()
-    <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
-    <tr><th>Sender:</th><td><input type="text" name="sender" /></td></tr>
-    <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
+    <tr class="required"><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr>
+    <tr class="required"><th>Message:</th><td><input type="text" name="message" /></td></tr>
+    <tr class="required"><th>Sender:</th><td><input type="text" name="sender" /></td></tr>
+    <tr class="required"><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
     >>> print f.as_ul()
-    <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
-    <li>Message: <input type="text" name="message" /></li>
-    <li>Sender: <input type="text" name="sender" /></li>
-    <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
+    <li class="required">Subject: <input type="text" name="subject" maxlength="100" /></li>
+    <li class="required">Message: <input type="text" name="message" /></li>
+    <li class="required">Sender: <input type="text" name="sender" /></li>
+    <li class="required">Cc myself: <input type="checkbox" name="cc_myself" /></li>
     >>> print f.as_p()
-    <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
-    <p>Message: <input type="text" name="message" /></p>
-    <p>Sender: <input type="text" name="sender" /></p>
-    <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
+    <p class="required">Subject: <input type="text" name="subject" maxlength="100" /></p>
+    <p class="required">Message: <input type="text" name="message" /></p>
+    <p class="required">Sender: <input type="text" name="sender" /></p>
+    <p class="required">Cc myself: <input type="checkbox" name="cc_myself" /></p>
 
 If ``auto_id`` is set to ``True``, then the form output *will* include
 ``<label>`` tags and will simply use the field name as its ``id`` for each form
@@ -435,20 +435,20 @@
 
     >>> f = ContactForm(auto_id=True)
     >>> print f.as_table()
-    <tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr>
-    <tr><th><label for="sender">Sender:</label></th><td><input type="text" name="sender" id="sender" /></td></tr>
-    <tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr>
+    <tr class="required"><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr>
+    <tr class="required"><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr>
+    <tr class="required"><th><label for="sender">Sender:</label></th><td><input type="text" name="sender" id="sender" /></td></tr>
+    <tr class="required"><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr>
     >>> print f.as_ul()
-    <li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li>
-    <li><label for="message">Message:</label> <input type="text" name="message" id="message" /></li>
-    <li><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></li>
-    <li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li>
+    <li class="required"><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li>
+    <li class="required"><label for="message">Message:</label> <input type="text" name="message" id="message" /></li>
+    <li class="required"><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></li>
+    <li class="required"><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li>
     >>> print f.as_p()
-    <p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p>
-    <p><label for="message">Message:</label> <input type="text" name="message" id="message" /></p>
-    <p><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></p>
-    <p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p>
+    <p class="required"><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p>
+    <p class="required"><label for="message">Message:</label> <input type="text" name="message" id="message" /></p>
+    <p class="required"><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></p>
+    <p class="required"><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p>
 
 If ``auto_id`` is set to a string containing the format character ``'%s'``,
 then the form output will include ``<label>`` tags, and will generate ``id``
@@ -458,20 +458,20 @@
 
     >>> f = ContactForm(auto_id='id_for_%s')
     >>> print f.as_table()
-    <tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr>
-    <tr><th><label for="id_for_sender">Sender:</label></th><td><input type="text" name="sender" id="id_for_sender" /></td></tr>
-    <tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr>
+    <tr class="required"><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr>
+    <tr class="required"><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr>
+    <tr class="required"><th><label for="id_for_sender">Sender:</label></th><td><input type="text" name="sender" id="id_for_sender" /></td></tr>
+    <tr class="required"><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr>
     >>> print f.as_ul()
-    <li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
-    <li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li>
-    <li><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></li>
-    <li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
+    <li class="required"><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
+    <li class="required"><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li>
+    <li class="required"><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></li>
+    <li class="required"><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
     >>> print f.as_p()
-    <p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p>
-    <p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p>
-    <p><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></p>
-    <p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p>
+    <p class="required"><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p>
+    <p class="required"><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p>
+    <p class="required"><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></p>
+    <p class="required"><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p>
 
 If ``auto_id`` is set to any other true value -- such as a string that doesn't
 include ``%s`` -- then the library will act as if ``auto_id`` is ``True``.
@@ -501,23 +501,27 @@
     ...         'cc_myself': True}
     >>> f = ContactForm(data, auto_id=False)
     >>> print f.as_table()
-    <tr><th>Subject:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th>Message:</th><td><input type="text" name="message" value="Hi there" /></td></tr>
-    <tr><th>Sender:</th><td><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul><input type="text" name="sender" value="invalid e-mail address" /></td></tr>
-    <tr><th>Cc myself:</th><td><input checked="checked" type="checkbox" name="cc_myself" /></td></tr>
+    <tr class="error required"><th>Subject:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="subject" maxlength="100" /></td></tr>
+    <tr class="required"><th>Message:</th><td><input type="text" name="message" value="Hi there" /></td></tr>
+    <tr class="error required"><th>Sender:</th><td><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul><input type="text" name="sender" value="invalid e-mail address" /></td></tr>
+    <tr class="required"><th>Cc myself:</th><td><input checked="checked" type="checkbox" name="cc_myself" /></td></tr>
     >>> print f.as_ul()
-    <li><ul class="errorlist"><li>This field is required.</li></ul>Subject: <input type="text" name="subject" maxlength="100" /></li>
-    <li>Message: <input type="text" name="message" value="Hi there" /></li>
-    <li><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul>Sender: <input type="text" name="sender" value="invalid e-mail address" /></li>
-    <li>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></li>
+    <li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Subject: <input type="text" name="subject" maxlength="100" /></li>
+    <li class="required">Message: <input type="text" name="message" value="Hi there" /></li>
+    <li class="error required"><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul>Sender: <input type="text" name="sender" value="invalid e-mail address" /></li>
+    <li class="required">Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></li>
     >>> print f.as_p()
     <p><ul class="errorlist"><li>This field is required.</li></ul></p>
-    <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
-    <p>Message: <input type="text" name="message" value="Hi there" /></p>
+    <p class="error required">Subject: <input type="text" name="subject" maxlength="100" /></p>
+    <p class="required">Message: <input type="text" name="message" value="Hi there" /></p>
     <p><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul></p>
-    <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>
+    <p class="error required">Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
+    <p class="required">Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
 
+You will notice that each row which is required is given the HTML class name
+``required`` and any row which the field did not pass validation receives the
+``error`` class name.
+
 More granular output
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -587,11 +591,11 @@
     ...     priority = forms.CharField()
     >>> f = ContactFormWithPriority(auto_id=False)
     >>> print f.as_ul()
-    <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
-    <li>Message: <input type="text" name="message" /></li>
-    <li>Sender: <input type="text" name="sender" /></li>
-    <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
-    <li>Priority: <input type="text" name="priority" /></li>
+    <li class="required">Subject: <input type="text" name="subject" maxlength="100" /></li>
+    <li class="required">Message: <input type="text" name="message" /></li>
+    <li class="required">Sender: <input type="text" name="sender" /></li>
+    <li class="required">Cc myself: <input type="checkbox" name="cc_myself" /></li>
+    <li class="required">Priority: <input type="text" name="priority" /></li>
 
 It's possible to subclass multiple forms, treating forms as "mix-ins." In this
 example, ``BeatleForm`` subclasses both ``PersonForm`` and ``InstrumentForm``
@@ -607,10 +611,10 @@
     ...     haircut_type = CharField()
     >>> b = BeatleForm(auto_id=False)
     >>> print b.as_ul()
-    <li>First name: <input type="text" name="first_name" /></li>
-    <li>Last name: <input type="text" name="last_name" /></li>
-    <li>Instrument: <input type="text" name="instrument" /></li>
-    <li>Haircut type: <input type="text" name="haircut_type" /></li>
+    <li class="required">First name: <input type="text" name="first_name" /></li>
+    <li class="required">Last name: <input type="text" name="last_name" /></li>
+    <li class="required">Instrument: <input type="text" name="instrument" /></li>
+    <li class="required">Haircut type: <input type="text" name="haircut_type" /></li>
 
 Fields
 ======
@@ -717,9 +721,9 @@
     ...     comment = forms.CharField()
     >>> f = CommentForm(auto_id=False)
     >>> print f
-    <tr><th>Your name:</th><td><input type="text" name="name" /></td></tr>
+    <tr class="required"><th>Your name:</th><td><input type="text" name="name" /></td></tr>
     <tr><th>Your Web site:</th><td><input type="text" name="url" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
+    <tr class="required"><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
 
 ``initial``
 ~~~~~~~~~~~
@@ -736,9 +740,9 @@
     ...     comment = forms.CharField()
     >>> f = CommentForm(auto_id=False)
     >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url" value="http://" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
+    <tr class="required"><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
+    <tr class="required"><th>Url:</th><td><input type="text" name="url" value="http://" /></td></tr>
+    <tr class="required"><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
 
 You may be thinking, why not just pass a dictionary of the initial values as
 data when displaying the form? Well, if you do that, you'll trigger validation,
@@ -751,9 +755,9 @@
     >>> default_data = {'name': 'Your name', 'url': 'http://'}
     >>> f = CommentForm(default_data, auto_id=False)
     >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
-    <tr><th>Url:</th><td><ul class="errorlist"><li>Enter a valid URL.</li></ul><input type="text" name="url" value="http://" /></td></tr>
-    <tr><th>Comment:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="comment" /></td></tr>
+    <tr class="required"><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
+    <tr class="required"><th>Url:</th><td><ul class="errorlist"><li>Enter a valid URL.</li></ul><input type="text" name="url" value="http://" /></td></tr>
+    <tr class="required"><th>Comment:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="comment" /></td></tr>
 
 This is why ``initial`` values are only displayed for unbound forms. For bound
 forms, the HTML output will use the bound data.
@@ -797,20 +801,20 @@
     ...     cc_myself = forms.BooleanField()
     >>> f = HelpTextContactForm(auto_id=False)
     >>> print f.as_table()
-    <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /><br />100 characters max.</td></tr>
-    <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
-    <tr><th>Sender:</th><td><input type="text" name="sender" /><br />A valid e-mail address, please.</td></tr>
-    <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
+    <tr class="required"><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /><br />100 characters max.</td></tr>
+    <tr class="required"><th>Message:</th><td><input type="text" name="message" /></td></tr>
+    <tr class="required"><th>Sender:</th><td><input type="text" name="sender" /><br />A valid e-mail address, please.</td></tr>
+    <tr class="required"><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
     >>> print f.as_ul()
-    <li>Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</li>
-    <li>Message: <input type="text" name="message" /></li>
-    <li>Sender: <input type="text" name="sender" /> A valid e-mail address, please.</li>
-    <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
+    <li class="required">Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</li>
+    <li class="required">Message: <input type="text" name="message" /></li>
+    <li class="required">Sender: <input type="text" name="sender" /> A valid e-mail address, please.</li>
+    <li class="required">Cc myself: <input type="checkbox" name="cc_myself" /></li>
     >>> print f.as_p()
-    <p>Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</p>
-    <p>Message: <input type="text" name="message" /></p>
-    <p>Sender: <input type="text" name="sender" /> A valid e-mail address, please.</p>
-    <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
+    <p class="required">Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</p>
+    <p class="required">Message: <input type="text" name="message" /></p>
+    <p class="required">Sender: <input type="text" name="sender" /> A valid e-mail address, please.</p>
+    <p class="required">Cc myself: <input type="checkbox" name="cc_myself" /></p>
 
 Dynamic initial values
 ----------------------
@@ -831,14 +835,14 @@
     ...     comment = forms.CharField()
     >>> f = CommentForm(initial={'name': 'your username'}, auto_id=False)
     >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="your username" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
+    <tr class="required"><th>Name:</th><td><input type="text" name="name" value="your username" /></td></tr>
+    <tr class="required"><th>Url:</th><td><input type="text" name="url" /></td></tr>
+    <tr class="required"><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
     >>> f = CommentForm(initial={'name': 'another username'}, auto_id=False)
     >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="another username" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
+    <tr class="required"><th>Name:</th><td><input type="text" name="name" value="another username" /></td></tr>
+    <tr class="required"><th>Url:</th><td><input type="text" name="url" /></td></tr>
+    <tr class="required"><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
 
 Just like the ``initial`` parameter to ``Field``, these values are only
 displayed for unbound forms, and they're not used as fallback values if a
@@ -855,9 +859,9 @@
     ...     comment = forms.CharField()
     >>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
     >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="instance" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
+    <tr class="required"><th>Name:</th><td><input type="text" name="name" value="instance" /></td></tr>
+    <tr class="required"><th>Url:</th><td><input type="text" name="url" /></td></tr>
+    <tr class="required"><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
 
 More coming soon
 ================
Index: tests/regressiontests/forms/tests.py
===================================================================
--- tests/regressiontests/forms/tests.py	(revision 4732)
+++ tests/regressiontests/forms/tests.py	(working copy)
@@ -335,12 +335,12 @@
 ...     somechoice = ChoiceField(choices=chain((('', '-'*9),), [(thing['id'], thing['name']) for thing in things]))
 >>> f = SomeForm()
 >>> f.as_table()
-u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>'
+u'<tr class="required"><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>'
 >>> f.as_table()
-u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>'
+u'<tr class="required"><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>'
 >>> f = SomeForm({'somechoice': 2})
 >>> f.as_table()
-u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="">---------</option>\n<option value="1">And Boom</option>\n<option value="2" selected="selected">One More Thing!</option>\n</select></td></tr>'
+u'<tr class="required"><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="">---------</option>\n<option value="1">And Boom</option>\n<option value="2" selected="selected">One More Thing!</option>\n</select></td></tr>'
 
 You can also pass 'choices' to the constructor:
 >>> w = Select(choices=[(1, 1), (2, 2), (3, 3)])
@@ -1768,9 +1768,9 @@
 Last name Lennon
 Birthday 1940-10-9
 >>> print p
-<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>
-<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="Lennon" id="id_last_name" /></td></tr>
-<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>
+<tr class="required"><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>
+<tr class="required"><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="Lennon" id="id_last_name" /></td></tr>
+<tr class="required"><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>
 
 Empty dictionaries are valid, too.
 >>> p = Person({})
@@ -1785,24 +1785,24 @@
 ...
 AttributeError: 'Person' object has no attribute 'clean_data'
 >>> print p
-<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
-<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>
-<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>
+<tr class="error required"><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
+<tr class="error required"><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>
+<tr class="error required"><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>
 >>> print p.as_table()
-<tr><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
-<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>
-<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>
+<tr class="error required"><th><label for="id_first_name">First name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="first_name" id="id_first_name" /></td></tr>
+<tr class="error required"><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>
+<tr class="error required"><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>
 >>> print p.as_ul()
-<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>
-<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>
-<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>
+<li class="error required"><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>
+<li class="error required"><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>
+<li class="error required"><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>
 >>> print p.as_p()
 <p><ul class="errorlist"><li>This field is required.</li></ul></p>
-<p><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
+<p class="error required"><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
 <p><ul class="errorlist"><li>This field is required.</li></ul></p>
-<p><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
+<p class="error required"><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
 <p><ul class="errorlist"><li>This field is required.</li></ul></p>
-<p><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>
+<p class="error required"><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_birthday" /></p>
 
 If you don't pass any values to the Form's __init__(), or if you pass None,
 the Form will be considered unbound and won't do any validation. Form.errors
@@ -1819,30 +1819,30 @@
 ...
 AttributeError: 'Person' object has no attribute 'clean_data'
 >>> print p
-<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
-<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
-<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>
+<tr class="required"><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
+<tr class="required"><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
+<tr class="required"><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>
 >>> print p.as_table()
-<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
-<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
-<tr><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" id="id_birthday" /></td></tr>
+<tr class="required"><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
+<tr class="required"><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
+<tr class="required"><th><label for="id_birthday">Birthday:</label></th><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>
+<li class="required"><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
+<li class="required"><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
+<li class="required"><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>
+<p class="required"><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
+<p class="required"><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
+<p class="required"><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" id="id_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'})
 >>> p.as_table()
-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>'
+u'<tr class="required"><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 class="required"><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 class="required"><th><label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></td></tr>'
 >>> p.as_ul()
-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>'
+u'<li class="required"><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></li>\n<li class="required"><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 class="required"><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></li>'
 >>> p.as_p()
-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>'
+u'<p class="required"><label for="id_first_name">First name:</label> <input type="text" name="first_name" value="John" id="id_first_name" /></p>\n<p class="required"><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 class="required"><label for="id_birthday">Birthday:</label> <input type="text" name="birthday" value="1940-10-9" id="id_birthday" /></p>'
 
 >>> p = Person({'last_name': u'Lennon'})
 >>> p.errors
@@ -1892,33 +1892,33 @@
 the human-readable labels for a field.
 >>> p = Person(auto_id='%s_id')
 >>> print p.as_table()
-<tr><th><label for="first_name_id">First name:</label></th><td><input type="text" name="first_name" id="first_name_id" /></td></tr>
-<tr><th><label for="last_name_id">Last name:</label></th><td><input type="text" name="last_name" id="last_name_id" /></td></tr>
-<tr><th><label for="birthday_id">Birthday:</label></th><td><input type="text" name="birthday" id="birthday_id" /></td></tr>
+<tr class="required"><th><label for="first_name_id">First name:</label></th><td><input type="text" name="first_name" id="first_name_id" /></td></tr>
+<tr class="required"><th><label for="last_name_id">Last name:</label></th><td><input type="text" name="last_name" id="last_name_id" /></td></tr>
+<tr class="required"><th><label for="birthday_id">Birthday:</label></th><td><input type="text" name="birthday" id="birthday_id" /></td></tr>
 >>> print p.as_ul()
-<li><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></li>
-<li><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></li>
-<li><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></li>
+<li class="required"><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></li>
+<li class="required"><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></li>
+<li class="required"><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></li>
 >>> print p.as_p()
-<p><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></p>
-<p><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></p>
-<p><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></p>
+<p class="required"><label for="first_name_id">First name:</label> <input type="text" name="first_name" id="first_name_id" /></p>
+<p class="required"><label for="last_name_id">Last name:</label> <input type="text" name="last_name" id="last_name_id" /></p>
+<p class="required"><label for="birthday_id">Birthday:</label> <input type="text" name="birthday" id="birthday_id" /></p>
 
 If auto_id is any True value whose str() does not contain '%s', the "id"
 attribute will be the name of the field.
 >>> p = Person(auto_id=True)
 >>> print p.as_ul()
-<li><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /></li>
-<li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
-<li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>
+<li class="required"><label for="first_name">First name:</label> <input type="text" name="first_name" id="first_name" /></li>
+<li class="required"><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
+<li class="required"><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>
 
 If auto_id is any False value, an "id" attribute won't be output unless it
 was manually entered.
 >>> p = Person(auto_id=False)
 >>> print p.as_ul()
-<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>
+<li class="required">First name: <input type="text" name="first_name" /></li>
+<li class="required">Last name: <input type="text" name="last_name" /></li>
+<li class="required">Birthday: <input type="text" name="birthday" /></li>
 
 In this example, auto_id is False, but the "id" attribute for the "first_name"
 field is given. Also note that field gets a <label>, while the others don't.
@@ -1928,17 +1928,17 @@
 ...     birthday = DateField()
 >>> p = PersonNew(auto_id=False)
 >>> print p.as_ul()
-<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
-<li>Last name: <input type="text" name="last_name" /></li>
-<li>Birthday: <input type="text" name="birthday" /></li>
+<li class="required"><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
+<li class="required">Last name: <input type="text" name="last_name" /></li>
+<li class="required">Birthday: <input type="text" name="birthday" /></li>
 
 If the "id" attribute is specified in the Form and auto_id is True, the "id"
 attribute in the Form gets precedence.
 >>> p = PersonNew(auto_id=True)
 >>> print p.as_ul()
-<li><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
-<li><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
-<li><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>
+<li class="required"><label for="first_name_id">First name:</label> <input type="text" id="first_name_id" name="first_name" /></li>
+<li class="required"><label for="last_name">Last name:</label> <input type="text" name="last_name" id="last_name" /></li>
+<li class="required"><label for="birthday">Birthday:</label> <input type="text" name="birthday" id="birthday" /></li>
 
 >>> class SignupForm(Form):
 ...     email = EmailField()
@@ -2086,14 +2086,14 @@
 <li><label><input type="radio" name="language" value="J" /> Java</label></li>
 </ul>
 >>> print f
-<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
-<tr><th>Language:</th><td><ul>
+<tr class="required"><th>Name:</th><td><input type="text" name="name" /></td></tr>
+<tr class="required"><th>Language:</th><td><ul>
 <li><label><input type="radio" name="language" value="P" /> Python</label></li>
 <li><label><input type="radio" name="language" value="J" /> Java</label></li>
 </ul></td></tr>
 >>> print f.as_ul()
-<li>Name: <input type="text" name="name" /></li>
-<li>Language: <ul>
+<li class="required">Name: <input type="text" name="name" /></li>
+<li class="required">Language: <ul>
 <li><label><input type="radio" name="language" value="P" /> Python</label></li>
 <li><label><input type="radio" name="language" value="J" /> Java</label></li>
 </ul></li>
@@ -2112,20 +2112,20 @@
 either as_table() or as_ul(), the label for the RadioSelect will point to the
 ID of the *first* radio button.
 >>> print f
-<tr><th><label for="id_name">Name:</label></th><td><input type="text" name="name" id="id_name" /></td></tr>
-<tr><th><label for="id_language_0">Language:</label></th><td><ul>
+<tr class="required"><th><label for="id_name">Name:</label></th><td><input type="text" name="name" id="id_name" /></td></tr>
+<tr class="required"><th><label for="id_language_0">Language:</label></th><td><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></td></tr>
 >>> print f.as_ul()
-<li><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></li>
-<li><label for="id_language_0">Language:</label> <ul>
+<li class="required"><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></li>
+<li class="required"><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></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>
+<p class="required"><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p>
+<p class="required"><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>
@@ -2223,7 +2223,7 @@
 ...     composers = MultipleChoiceField(choices=[('J', 'John Lennon'), ('P', 'Paul McCartney')], widget=MultipleHiddenInput)
 >>> f = SongFormHidden(MultiValueDict(dict(name=['Yesterday'], composers=['J', 'P'])), auto_id=False)
 >>> print f.as_ul()
-<li>Name: <input type="text" name="name" value="Yesterday" /><input type="hidden" name="composers" value="J" />
+<li class="required">Name: <input type="text" name="name" value="Yesterday" /><input type="hidden" name="composers" value="J" />
 <input type="hidden" name="composers" value="P" /></li>
 
 When using CheckboxSelectMultiple, the framework expects a list of input and
@@ -2250,10 +2250,10 @@
 
 >>> f = EscapingForm({'special_name': "Nothing to escape"}, auto_id=False)
 >>> print f
-<tr><th>Special name:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Nothing to escape&#39;</li></ul><input type="text" name="special_name" value="Nothing to escape" /></td></tr>
+<tr class="error required"><th>Special name:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Nothing to escape&#39;</li></ul><input type="text" name="special_name" value="Nothing to escape" /></td></tr>
 >>> f = EscapingForm({'special_name': "Should escape < & > and <script>alert('xss')</script>"}, auto_id=False)
 >>> print f
-<tr><th>Special name:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;&#39;</li></ul><input type="text" name="special_name" value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;" /></td></tr>
+<tr class="error required"><th>Special name:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;&#39;</li></ul><input type="text" name="special_name" value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;" /></td></tr>
 
 # Validating multiple fields in relation to another ###########################
 
@@ -2307,9 +2307,9 @@
 {}
 >>> f = UserRegistration({}, auto_id=False)
 >>> print f.as_table()
-<tr><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr>
-<tr><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr>
-<tr><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr>
+<tr class="error required"><th>Username:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="username" maxlength="10" /></td></tr>
+<tr class="error required"><th>Password1:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password1" /></td></tr>
+<tr class="error required"><th>Password2:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="password" name="password2" /></td></tr>
 >>> f.errors
 {'username': [u'This field is required.'], 'password1': [u'This field is required.'], 'password2': [u'This field is required.']}
 >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'bar'}, auto_id=False)
@@ -2317,14 +2317,14 @@
 {'__all__': [u'Please make sure your passwords match.']}
 >>> print f.as_table()
 <tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
-<tr><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
-<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
-<tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>
+<tr class="required"><th>Username:</th><td><input type="text" name="username" value="adrian" maxlength="10" /></td></tr>
+<tr class="required"><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
+<tr class="required"><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>
 >>> print f.as_ul()
 <li><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></li>
-<li>Username: <input type="text" name="username" value="adrian" maxlength="10" /></li>
-<li>Password1: <input type="password" name="password1" value="foo" /></li>
-<li>Password2: <input type="password" name="password2" value="bar" /></li>
+<li class="required">Username: <input type="text" name="username" value="adrian" maxlength="10" /></li>
+<li class="required">Password1: <input type="password" name="password1" value="foo" /></li>
+<li class="required">Password2: <input type="password" name="password2" value="bar" /></li>
 >>> f = UserRegistration({'username': 'adrian', 'password1': 'foo', 'password2': 'foo'}, auto_id=False)
 >>> f.errors
 {}
@@ -2344,9 +2344,9 @@
 ...         self.fields['birthday'] = DateField()
 >>> p = Person(auto_id=False)
 >>> print p
-<tr><th>First name:</th><td><input type="text" name="first_name" /></td></tr>
-<tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr>
-<tr><th>Birthday:</th><td><input type="text" name="birthday" /></td></tr>
+<tr class="required"><th>First name:</th><td><input type="text" name="first_name" /></td></tr>
+<tr class="required"><th>Last name:</th><td><input type="text" name="last_name" /></td></tr>
+<tr class="required"><th>Birthday:</th><td><input type="text" name="birthday" /></td></tr>
 
 Instances of a dynamic Form do not persist fields from one Form instance to
 the next.
@@ -2358,13 +2358,13 @@
 >>> field_list = [('field1', CharField()), ('field2', CharField())]
 >>> my_form = MyForm(field_list=field_list)
 >>> print my_form
-<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
-<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
+<tr class="required"><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
+<tr class="required"><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
 >>> field_list = [('field3', CharField()), ('field4', CharField())]
 >>> my_form = MyForm(field_list=field_list)
 >>> print my_form
-<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
-<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
+<tr class="required"><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
+<tr class="required"><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
 
 >>> class MyForm(Form):
 ...     default_field_1 = CharField()
@@ -2376,17 +2376,17 @@
 >>> field_list = [('field1', CharField()), ('field2', CharField())]
 >>> my_form = MyForm(field_list=field_list)
 >>> print my_form
-<tr><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr>
-<tr><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr>
-<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
-<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
+<tr class="required"><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr>
+<tr class="required"><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr>
+<tr class="required"><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
+<tr class="required"><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
 >>> field_list = [('field3', CharField()), ('field4', CharField())]
 >>> my_form = MyForm(field_list=field_list)
 >>> print my_form
-<tr><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr>
-<tr><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr>
-<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
-<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
+<tr class="required"><th>Default field 1:</th><td><input type="text" name="default_field_1" /></td></tr>
+<tr class="required"><th>Default field 2:</th><td><input type="text" name="default_field_2" /></td></tr>
+<tr class="required"><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
+<tr class="required"><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
 
 Similarly, changes to field attributes do not persist from one Form instance
 to the next.
@@ -2436,32 +2436,32 @@
 ...     birthday = DateField()
 >>> p = Person(auto_id=False)
 >>> print p
-<tr><th>First name:</th><td><input type="text" name="first_name" /></td></tr>
-<tr><th>Last name:</th><td><input type="text" name="last_name" /></td></tr>
-<tr><th>Birthday:</th><td><input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></td></tr>
+<tr class="required"><th>First name:</th><td><input type="text" name="first_name" /></td></tr>
+<tr class="required"><th>Last name:</th><td><input type="text" name="last_name" /></td></tr>
+<tr class="required"><th>Birthday:</th><td><input type="text" name="birthday" /><input type="hidden" name="hidden_text" /></td></tr>
 >>> print p.as_ul()
-<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>
+<li class="required">First name: <input type="text" name="first_name" /></li>
+<li class="required">Last name: <input type="text" name="last_name" /></li>
+<li class="required">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>
+<p class="required">First name: <input type="text" name="first_name" /></p>
+<p class="required">Last name: <input type="text" name="last_name" /></p>
+<p class="required">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')
 >>> print p
-<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
-<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
-<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>
+<tr class="required"><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" id="id_first_name" /></td></tr>
+<tr class="required"><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" id="id_last_name" /></td></tr>
+<tr class="required"><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>
 >>> 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" /><input type="hidden" name="hidden_text" id="id_hidden_text" /></li>
+<li class="required"><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></li>
+<li class="required"><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></li>
+<li class="required"><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>
+<p class="required"><label for="id_first_name">First name:</label> <input type="text" name="first_name" id="id_first_name" /></p>
+<p class="required"><label for="id_last_name">Last name:</label> <input type="text" name="last_name" id="id_last_name" /></p>
+<p class="required"><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]) "
@@ -2470,19 +2470,19 @@
 >>> p = Person({'first_name': 'John', 'last_name': 'Lennon', 'birthday': '1940-10-9'}, auto_id=False)
 >>> print p
 <tr><td colspan="2"><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></td></tr>
-<tr><th>First name:</th><td><input type="text" name="first_name" value="John" /></td></tr>
-<tr><th>Last name:</th><td><input type="text" name="last_name" value="Lennon" /></td></tr>
-<tr><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr>
+<tr class="required"><th>First name:</th><td><input type="text" name="first_name" value="John" /></td></tr>
+<tr class="required"><th>Last name:</th><td><input type="text" name="last_name" value="Lennon" /></td></tr>
+<tr class="required"><th>Birthday:</th><td><input type="text" name="birthday" value="1940-10-9" /><input type="hidden" name="hidden_text" /></td></tr>
 >>> print p.as_ul()
 <li><ul class="errorlist"><li>(Hidden field hidden_text) This field is required.</li></ul></li>
-<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>
+<li class="required">First name: <input type="text" name="first_name" value="John" /></li>
+<li class="required">Last name: <input type="text" name="last_name" value="Lennon" /></li>
+<li class="required">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>
+<p class="required">First name: <input type="text" name="first_name" value="John" /></p>
+<p class="required">Last name: <input type="text" name="last_name" value="Lennon" /></p>
+<p class="required">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):
@@ -2514,20 +2514,20 @@
 ...     field14 = CharField()
 >>> p = TestForm(auto_id=False)
 >>> print p
-<tr><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
-<tr><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
-<tr><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
-<tr><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
-<tr><th>Field5:</th><td><input type="text" name="field5" /></td></tr>
-<tr><th>Field6:</th><td><input type="text" name="field6" /></td></tr>
-<tr><th>Field7:</th><td><input type="text" name="field7" /></td></tr>
-<tr><th>Field8:</th><td><input type="text" name="field8" /></td></tr>
-<tr><th>Field9:</th><td><input type="text" name="field9" /></td></tr>
-<tr><th>Field10:</th><td><input type="text" name="field10" /></td></tr>
-<tr><th>Field11:</th><td><input type="text" name="field11" /></td></tr>
-<tr><th>Field12:</th><td><input type="text" name="field12" /></td></tr>
-<tr><th>Field13:</th><td><input type="text" name="field13" /></td></tr>
-<tr><th>Field14:</th><td><input type="text" name="field14" /></td></tr>
+<tr class="required"><th>Field1:</th><td><input type="text" name="field1" /></td></tr>
+<tr class="required"><th>Field2:</th><td><input type="text" name="field2" /></td></tr>
+<tr class="required"><th>Field3:</th><td><input type="text" name="field3" /></td></tr>
+<tr class="required"><th>Field4:</th><td><input type="text" name="field4" /></td></tr>
+<tr class="required"><th>Field5:</th><td><input type="text" name="field5" /></td></tr>
+<tr class="required"><th>Field6:</th><td><input type="text" name="field6" /></td></tr>
+<tr class="required"><th>Field7:</th><td><input type="text" name="field7" /></td></tr>
+<tr class="required"><th>Field8:</th><td><input type="text" name="field8" /></td></tr>
+<tr class="required"><th>Field9:</th><td><input type="text" name="field9" /></td></tr>
+<tr class="required"><th>Field10:</th><td><input type="text" name="field10" /></td></tr>
+<tr class="required"><th>Field11:</th><td><input type="text" name="field11" /></td></tr>
+<tr class="required"><th>Field12:</th><td><input type="text" name="field12" /></td></tr>
+<tr class="required"><th>Field13:</th><td><input type="text" name="field13" /></td></tr>
+<tr class="required"><th>Field14:</th><td><input type="text" name="field14" /></td></tr>
 
 Some Field classes have an effect on the HTML attributes of their associated
 Widget. If you set max_length in a CharField and its associated widget is
@@ -2540,10 +2540,10 @@
 ...    address = CharField()                                 # no max_length defined here
 >>> p = UserRegistration(auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" maxlength="10" /></li>
-<li>Password: <input type="password" name="password" maxlength="10" /></li>
-<li>Realname: <input type="text" name="realname" maxlength="10" /></li>
-<li>Address: <input type="text" name="address" /></li>
+<li class="required">Username: <input type="text" name="username" maxlength="10" /></li>
+<li class="required">Password: <input type="password" name="password" maxlength="10" /></li>
+<li class="required">Realname: <input type="text" name="realname" maxlength="10" /></li>
+<li class="required">Address: <input type="text" name="address" /></li>
 
 If you specify a custom "attrs" that includes the "maxlength" attribute,
 the Field's max_length attribute will override whatever "maxlength" you specify
@@ -2553,8 +2553,8 @@
 ...    password = CharField(max_length=10, widget=PasswordInput)
 >>> p = UserRegistration(auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" maxlength="10" /></li>
-<li>Password: <input type="password" name="password" maxlength="10" /></li>
+<li class="required">Username: <input type="text" name="username" maxlength="10" /></li>
+<li class="required">Password: <input type="password" name="password" maxlength="10" /></li>
 
 # Specifying labels ###########################################################
 
@@ -2567,9 +2567,9 @@
 ...    password2 = CharField(widget=PasswordInput, label='Password (again)')
 >>> p = UserRegistration(auto_id=False)
 >>> print p.as_ul()
-<li>Your username: <input type="text" name="username" maxlength="10" /></li>
-<li>Password1: <input type="password" name="password1" /></li>
-<li>Password (again): <input type="password" name="password2" /></li>
+<li class="required">Your username: <input type="text" name="username" maxlength="10" /></li>
+<li class="required">Password1: <input type="password" name="password1" /></li>
+<li class="required">Password (again): <input type="password" name="password2" /></li>
 
 A label can be a Unicode object or a bytestring with special characters.
 >>> class UserRegistration(Form):
@@ -2577,7 +2577,7 @@
 ...    password = CharField(widget=PasswordInput, label=u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111')
 >>> p = UserRegistration(auto_id=False)
 >>> p.as_ul()
-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>'
+u'<li class="required">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="text" name="username" maxlength="10" /></li>\n<li class="required">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111: <input type="password" name="password" /></li>'
 
 If a label is set to the empty string for a field, that field won't get a label.
 >>> class UserRegistration(Form):
@@ -2585,12 +2585,12 @@
 ...    password = CharField(widget=PasswordInput)
 >>> p = UserRegistration(auto_id=False)
 >>> print p.as_ul()
-<li> <input type="text" name="username" maxlength="10" /></li>
-<li>Password: <input type="password" name="password" /></li>
+<li class="required"> <input type="text" name="username" maxlength="10" /></li>
+<li class="required">Password: <input type="password" name="password" /></li>
 >>> p = UserRegistration(auto_id='id_%s')
 >>> print p.as_ul()
-<li> <input id="id_username" type="text" name="username" maxlength="10" /></li>
-<li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>
+<li class="required"> <input id="id_username" type="text" name="username" maxlength="10" /></li>
+<li class="required"><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>
 
 If label is None, Django will auto-create the label from the field name. This
 is default behavior.
@@ -2599,12 +2599,12 @@
 ...    password = CharField(widget=PasswordInput)
 >>> p = UserRegistration(auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" maxlength="10" /></li>
-<li>Password: <input type="password" name="password" /></li>
+<li class="required">Username: <input type="text" name="username" maxlength="10" /></li>
+<li class="required">Password: <input type="password" name="password" /></li>
 >>> p = UserRegistration(auto_id='id_%s')
 >>> print p.as_ul()
-<li><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="10" /></li>
-<li><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>
+<li class="required"><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="10" /></li>
+<li class="required"><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></li>
 
 # Initial data ################################################################
 
@@ -2620,22 +2620,22 @@
 Here, we're not submitting any data, so the initial value will be displayed.
 >>> p = UserRegistration(auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
-<li>Password: <input type="password" name="password" /></li>
+<li class="required">Username: <input type="text" name="username" value="django" maxlength="10" /></li>
+<li class="required">Password: <input type="password" name="password" /></li>
 
 Here, we're submitting data, so the initial value will *not* be displayed.
 >>> p = UserRegistration({}, auto_id=False)
 >>> print p.as_ul()
-<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
-<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 >>> p = UserRegistration({'username': u''}, auto_id=False)
 >>> print p.as_ul()
-<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
-<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 >>> p = UserRegistration({'username': u'foo'}, auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
-<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+<li class="required">Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
 An 'initial' value is *not* used as a fallback if data is not provided. In this
 example, we don't provide a value for 'username', and the form raises a
@@ -2661,26 +2661,26 @@
 Here, we're not submitting any data, so the initial value will be displayed.
 >>> p = UserRegistration(initial={'username': 'django'}, auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" value="django" maxlength="10" /></li>
-<li>Password: <input type="password" name="password" /></li>
+<li class="required">Username: <input type="text" name="username" value="django" maxlength="10" /></li>
+<li class="required">Password: <input type="password" name="password" /></li>
 >>> p = UserRegistration(initial={'username': 'stephane'}, auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" value="stephane" maxlength="10" /></li>
-<li>Password: <input type="password" name="password" /></li>
+<li class="required">Username: <input type="text" name="username" value="stephane" maxlength="10" /></li>
+<li class="required">Password: <input type="password" name="password" /></li>
 
 The 'initial' parameter is meaningless if you pass data.
 >>> p = UserRegistration({}, initial={'username': 'django'}, auto_id=False)
 >>> print p.as_ul()
-<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
-<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 >>> p = UserRegistration({'username': u''}, initial={'username': 'django'}, auto_id=False)
 >>> print p.as_ul()
-<li><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
-<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Username: <input type="text" name="username" maxlength="10" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 >>> p = UserRegistration({'username': u'foo'}, initial={'username': 'django'}, auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
-<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
+<li class="required">Username: <input type="text" name="username" value="foo" maxlength="10" /></li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /></li>
 
 A dynamic 'initial' value is *not* used as a fallback if data is not provided.
 In this example, we don't provide a value for 'username', and the form raises a
@@ -2698,8 +2698,8 @@
 ...    password = CharField(widget=PasswordInput)
 >>> p = UserRegistration(initial={'username': 'babik'}, auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" value="babik" maxlength="10" /></li>
-<li>Password: <input type="password" name="password" /></li>
+<li class="required">Username: <input type="text" name="username" value="babik" maxlength="10" /></li>
+<li class="required">Password: <input type="password" name="password" /></li>
 
 # Help text ###################################################################
 
@@ -2710,20 +2710,20 @@
 ...    password = CharField(widget=PasswordInput, help_text='Choose wisely.')
 >>> p = UserRegistration(auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li>
-<li>Password: <input type="password" name="password" /> Choose wisely.</li>
+<li class="required">Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li>
+<li class="required">Password: <input type="password" name="password" /> Choose wisely.</li>
 >>> print p.as_p()
-<p>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</p>
-<p>Password: <input type="password" name="password" /> Choose wisely.</p>
+<p class="required">Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</p>
+<p class="required">Password: <input type="password" name="password" /> Choose wisely.</p>
 >>> print p.as_table()
-<tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /><br />e.g., user@example.com</td></tr>
-<tr><th>Password:</th><td><input type="password" name="password" /><br />Choose wisely.</td></tr>
+<tr class="required"><th>Username:</th><td><input type="text" name="username" maxlength="10" /><br />e.g., user@example.com</td></tr>
+<tr class="required"><th>Password:</th><td><input type="password" name="password" /><br />Choose wisely.</td></tr>
 
 The help text is displayed whether or not data is provided for the form.
 >>> p = UserRegistration({'username': u'foo'}, auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" value="foo" maxlength="10" /> e.g., user@example.com</li>
-<li><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> Choose wisely.</li>
+<li class="required">Username: <input type="text" name="username" value="foo" maxlength="10" /> e.g., user@example.com</li>
+<li class="error required"><ul class="errorlist"><li>This field is required.</li></ul>Password: <input type="password" name="password" /> Choose wisely.</li>
 
 help_text is not displayed for hidden fields. It can be used for documentation
 purposes, though.
@@ -2733,15 +2733,15 @@
 ...    next = CharField(widget=HiddenInput, initial='/', help_text='Redirect destination')
 >>> p = UserRegistration(auto_id=False)
 >>> print p.as_ul()
-<li>Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li>
-<li>Password: <input type="password" name="password" /><input type="hidden" name="next" value="/" /></li>
+<li class="required">Username: <input type="text" name="username" maxlength="10" /> e.g., user@example.com</li>
+<li class="required">Password: <input type="password" name="password" /><input type="hidden" name="next" value="/" /></li>
 
 Help text can include arbitrary Unicode characters.
 >>> class UserRegistration(Form):
 ...    username = CharField(max_length=10, help_text='ŠĐĆŽćžšđ')
 >>> p = UserRegistration(auto_id=False)
 >>> p.as_ul()
-u'<li>Username: <input type="text" name="username" maxlength="10" /> \u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</li>'
+u'<li class="required">Username: <input type="text" name="username" maxlength="10" /> \u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</li>'
 
 # Subclassing forms ###########################################################
 
@@ -2756,15 +2756,15 @@
 ...     instrument = CharField()
 >>> p = Person(auto_id=False)
 >>> print p.as_ul()
-<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>
+<li class="required">First name: <input type="text" name="first_name" /></li>
+<li class="required">Last name: <input type="text" name="last_name" /></li>
+<li class="required">Birthday: <input type="text" name="birthday" /></li>
 >>> m = Musician(auto_id=False)
 >>> print m.as_ul()
-<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>
-<li>Instrument: <input type="text" name="instrument" /></li>
+<li class="required">First name: <input type="text" name="first_name" /></li>
+<li class="required">Last name: <input type="text" name="last_name" /></li>
+<li class="required">Birthday: <input type="text" name="birthday" /></li>
+<li class="required">Instrument: <input type="text" name="instrument" /></li>
 
 Yes, you can subclass multiple forms. The fields are added in the order in
 which the parent classes are listed.
@@ -2778,11 +2778,11 @@
 ...     haircut_type = CharField()
 >>> b = Beatle(auto_id=False)
 >>> print b.as_ul()
-<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>
-<li>Instrument: <input type="text" name="instrument" /></li>
-<li>Haircut type: <input type="text" name="haircut_type" /></li>
+<li class="required">First name: <input type="text" name="first_name" /></li>
+<li class="required">Last name: <input type="text" name="last_name" /></li>
+<li class="required">Birthday: <input type="text" name="birthday" /></li>
+<li class="required">Instrument: <input type="text" name="instrument" /></li>
+<li class="required">Haircut type: <input type="text" name="haircut_type" /></li>
 
 # Forms with prefixes #########################################################
 
@@ -2804,9 +2804,9 @@
 ... }
 >>> p = Person(data, prefix='person1')
 >>> print p.as_ul()
-<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>
-<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>
-<li><label for="id_person1-birthday">Birthday:</label> <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /></li>
+<li class="required"><label for="id_person1-first_name">First name:</label> <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" /></li>
+<li class="required"><label for="id_person1-last_name">Last name:</label> <input type="text" name="person1-last_name" value="Lennon" id="id_person1-last_name" /></li>
+<li class="required"><label for="id_person1-birthday">Birthday:</label> <input type="text" name="person1-birthday" value="1940-10-9" id="id_person1-birthday" /></li>
 >>> print p['first_name']
 <input type="text" name="person1-first_name" value="John" id="id_person1-first_name" />
 >>> print p['last_name']
@@ -2881,9 +2881,9 @@
 ...         return self.prefix and '%s-prefix-%s' % (self.prefix, field_name) or field_name
 >>> p = Person(prefix='foo')
 >>> print p.as_ul()
-<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>
-<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>
-<li><label for="id_foo-prefix-birthday">Birthday:</label> <input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" /></li>
+<li class="required"><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>
+<li class="required"><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>
+<li class="required"><label for="id_foo-prefix-birthday">Birthday:</label> <input type="text" name="foo-prefix-birthday" id="id_foo-prefix-birthday" /></li>
 >>> data = {
 ...     'foo-prefix-first_name': u'John',
 ...     'foo-prefix-last_name': u'Lennon',
@@ -2971,9 +2971,9 @@
 >>> print my_function('GET', {})
 <form action="" method="post">
 <table>
-<tr><th>Username:</th><td><input type="text" name="username" maxlength="10" /></td></tr>
-<tr><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
-<tr><th>Password2:</th><td><input type="password" name="password2" /></td></tr>
+<tr class="required"><th>Username:</th><td><input type="text" name="username" maxlength="10" /></td></tr>
+<tr class="required"><th>Password1:</th><td><input type="password" name="password1" /></td></tr>
+<tr class="required"><th>Password2:</th><td><input type="password" name="password2" /></td></tr>
 </table>
 <input type="submit" />
 </form>
@@ -2983,9 +2983,9 @@
 <form action="" method="post">
 <table>
 <tr><td colspan="2"><ul class="errorlist"><li>Please make sure your passwords match.</li></ul></td></tr>
-<tr><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters.</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr>
-<tr><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
-<tr><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>
+<tr class="error required"><th>Username:</th><td><ul class="errorlist"><li>Ensure this value has at most 10 characters.</li></ul><input type="text" name="username" value="this-is-a-long-username" maxlength="10" /></td></tr>
+<tr class="required"><th>Password1:</th><td><input type="password" name="password1" value="foo" /></td></tr>
+<tr class="required"><th>Password2:</th><td><input type="password" name="password2" value="bar" /></td></tr>
 </table>
 <input type="submit" />
 </form>
