Index: django/newforms/forms.py
===================================================================
--- django/newforms/forms.py	(revision 4563)
+++ django/newforms/forms.py	(working copy)
@@ -5,11 +5,12 @@
 from django.utils.datastructures import SortedDict, MultiValueDict
 from django.utils.html import escape
 from fields import Field
+from serializations import *
 from widgets import TextInput, Textarea, HiddenInput, MultipleHiddenInput
 from util import flatatt, StrAndUnicode, ErrorDict, ErrorList, ValidationError
 import copy
 
-__all__ = ('BaseForm', 'Form')
+__all__ = ('BaseForm', 'Form', 'SERIALIZATION_XHTML', 'SERIALIZATION_HTML401', 'SERIALIZATION_DEFAULT', 'SERIALIZATION_HTML_COMPATIBLE_XHTML1') 
 
 NON_FIELD_ERRORS = '__all__'
 
@@ -107,12 +108,12 @@
         """
         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, serialization=SERIALIZATION_DEFAULT):
         "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 = [], []
         for name, field in self.fields.items():
-            bf = BoundField(self, field, name)
+            bf = BoundField(self, field, name,serialization)
             bf_errors = ErrorList([escape(error) for error in bf.errors]) # Escape and cache in local variable.
             if bf.is_hidden:
                 if bf_errors:
@@ -139,17 +140,22 @@
                 output.append(str_hidden)
         return u'\n'.join(output)
 
-    def as_table(self):
+    def as_table(self,serialization=SERIALIZATION_DEFAULT):
         "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)
+        br = u'<br' + end_empty_element(u'br',serialization)
+        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, serialization)
 
-    def as_ul(self):
+    def as_ul(self,serialization=SERIALIZATION_DEFAULT):
         "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>%(errors)s%(label)s %(field)s%(help_text)s</li>', u'<li>%s</li>', '</li>', u' %s', False, serialization)
 
-    def as_p(self):
+    def as_p(self,serialization=SERIALIZATION_DEFAULT):
         "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>%(label)s %(field)s%(help_text)s</p>', u'<p>%s</p>', '</p>', u' %s', True, serialization)   
+    
+    def as_div(self,serialization=SERIALIZATION_DEFAULT):
+        "Returns this form rendered as HTML <div>s."
+        return self._html_output(u'<div>%(label)s %(field)s%(help_text)s</div>', u'<div>%s</div>', '</div>', u' %s', True, serialization)   
 
     def non_field_errors(self):
         """
@@ -209,7 +215,7 @@
 
 class BoundField(StrAndUnicode):
     "A Field plus data"
-    def __init__(self, form, field, name):
+    def __init__(self, form, field, name,serialization=SERIALIZATION_DEFAULT):
         self.form = form
         self.field = field
         self.name = name
@@ -219,12 +225,15 @@
         else:
             self.label = self.field.label
         self.help_text = field.help_text or ''
+        self.serialization=serialization
 
     def __unicode__(self):
         "Renders this field as an HTML widget."
         # Use the 'widget' attribute on the field to determine which type
         # of HTML widget to use.
-        value = self.as_widget(self.field.widget)
+        value = self.as_widget(widget=self.field.widget,
+                               attrs=None,
+                               serialization=self.serialization)
         if not isinstance(value, basestring):
             # Some Widget render() methods -- notably RadioSelect -- return a
             # "special" object rather than a string. Call the __str__() on that
@@ -240,7 +249,7 @@
         return self.form.errors.get(self.name, ErrorList())
     errors = property(_errors)
 
-    def as_widget(self, widget, attrs=None):
+    def as_widget(self, widget, attrs=None, serialization=SERIALIZATION_DEFAULT):
         attrs = attrs or {}
         auto_id = self.auto_id
         if auto_id and not attrs.has_key('id') and not widget.attrs.has_key('id'):
@@ -249,23 +258,23 @@
             data = self.form.initial.get(self.name, self.field.initial)
         else:
             data = self.data
-        return widget.render(self.html_name, data, attrs=attrs)
+        return widget.render(self.html_name, data, attrs=attrs, serialization=serialization)
 
-    def as_text(self, attrs=None):
+    def as_text(self, attrs=None, serialization=SERIALIZATION_DEFAULT):
         """
         Returns a string of HTML for representing this as an <input type="text">.
         """
-        return self.as_widget(TextInput(), attrs)
+        return self.as_widget(TextInput(), attrs, serialization)
 
-    def as_textarea(self, attrs=None):
+    def as_textarea(self, attrs=None, serialization=SERIALIZATION_DEFAULT):
         "Returns a string of HTML for representing this as a <textarea>."
         return self.as_widget(Textarea(), attrs)
 
-    def as_hidden(self, attrs=None):
+    def as_hidden(self, attrs=None, serialization=SERIALIZATION_DEFAULT):
         """
         Returns a string of HTML for representing this as an <input type="hidden">.
         """
-        return self.as_widget(self.field.hidden_widget(), attrs)
+        return self.as_widget(self.field.hidden_widget(), attrs, serialization)
 
     def _data(self):
         """
Index: django/newforms/widgets.py
===================================================================
--- django/newforms/widgets.py	(revision 4563)
+++ django/newforms/widgets.py	(working copy)
@@ -14,6 +14,7 @@
 from django.utils.html import escape
 from django.utils.translation import gettext
 from itertools import chain
+from serializations import end_empty_element, SERIALIZATION_DEFAULT
 
 try:
     set # Only available in Python 2.4+
@@ -26,7 +27,7 @@
     def __init__(self, attrs=None):
         self.attrs = attrs or {}
 
-    def render(self, name, value, attrs=None):
+    def render(self, name, value, attrs=None, serialization=SERIALIZATION_DEFAULT):
         """
         Returns this Widget rendered as HTML, as a Unicode string.
 
@@ -69,11 +70,11 @@
     """
     input_type = None # Subclasses must define this.
 
-    def render(self, name, value, attrs=None):
+    def render(self, name, value, attrs=None, serialization=SERIALIZATION_DEFAULT):
         if value is None: value = ''
         final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
         if value != '': final_attrs['value'] = smart_unicode(value) # Only add the 'value' attribute if a value is non-empty.
-        return u'<input%s />' % flatatt(final_attrs)
+        return u'<input%s%s' % (flatatt(final_attrs), end_empty_element(u'input',serialization));
 
 class TextInput(Input):
     input_type = 'text'
@@ -85,9 +86,9 @@
         self.attrs = attrs or {}
         self.render_value = render_value
 
-    def render(self, name, value, attrs=None):
+    def render(self, name, value, attrs=None, serialization=SERIALIZATION_DEFAULT):
         if not self.render_value: value=None
-        return super(PasswordInput, self).render(name, value, attrs)
+        return super(PasswordInput, self).render(name, value, attrs, serialization)
 
 class HiddenInput(Input):
     input_type = 'hidden'
@@ -103,10 +104,10 @@
         self.attrs = attrs or {}
         self.choices = choices
 
-    def render(self, name, value, attrs=None, choices=()):
+    def render(self, name, value, attrs=None, choices=(), serialization=SERIALIZATION_DEFAULT):
         if value is None: value = []
         final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
-        return u'\n'.join([(u'<input%s />' % flatatt(dict(value=smart_unicode(v), **final_attrs))) for v in value])
+        return u'\n'.join([(u'<input%s%s' % (flatatt(dict(value=smart_unicode(v), **final_attrs)), end_empty_element(u'input',serialization))) for v in value])
 
     def value_from_datadict(self, data, name):
         if isinstance(data, MultiValueDict):
@@ -117,7 +118,7 @@
     input_type = 'file'
 
 class Textarea(Widget):
-    def render(self, name, value, attrs=None):
+    def render(self, name, value, attrs=None, serialization=SERIALIZATION_DEFAULT):
         if value is None: value = ''
         value = smart_unicode(value)
         final_attrs = self.build_attrs(attrs, name=name)
@@ -130,7 +131,7 @@
         self.attrs = attrs or {}
         self.check_test = check_test
 
-    def render(self, name, value, attrs=None):
+    def render(self, name, value, attrs=None, serialization=SERIALIZATION_DEFAULT):
         final_attrs = self.build_attrs(attrs, type='checkbox', name=name)
         try:
             result = self.check_test(value)
@@ -140,7 +141,7 @@
             final_attrs['checked'] = 'checked'
         if value not in ('', True, False, None):
             final_attrs['value'] = smart_unicode(value) # Only add the 'value' attribute if a value is non-empty.
-        return u'<input%s />' % flatatt(final_attrs)
+        return u'<input%s%s' % (flatatt(final_attrs),end_empty_element(u'input',serialization))
 
 class Select(Widget):
     def __init__(self, attrs=None, choices=()):
@@ -150,7 +151,7 @@
         # more than once.
         self.choices = list(choices)
 
-    def render(self, name, value, attrs=None, choices=()):
+    def render(self, name, value, attrs=None, choices=(), serialization=SERIALIZATION_DEFAULT):
         if value is None: value = ''
         final_attrs = self.build_attrs(attrs, name=name)
         output = [u'<select%s>' % flatatt(final_attrs)]
@@ -170,12 +171,12 @@
         choices = ((u'1', gettext('Unknown')), (u'2', gettext('Yes')), (u'3', gettext('No')))
         super(NullBooleanSelect, self).__init__(attrs, choices)
 
-    def render(self, name, value, attrs=None, choices=()):
+    def render(self, name, value, attrs=None, choices=(), serialization=SERIALIZATION_DEFAULT):
         try:
             value = {True: u'2', False: u'3', u'2': u'2', u'3': u'3'}[value]
         except KeyError:
             value = u'1'
-        return super(NullBooleanSelect, self).render(name, value, attrs, choices)
+        return super(NullBooleanSelect, self).render(name, value, attrs, choices, serialization)
 
     def value_from_datadict(self, data, name):
         value = data.get(name, None)
@@ -187,7 +188,7 @@
         self.attrs = attrs or {}
         self.choices = choices
 
-    def render(self, name, value, attrs=None, choices=()):
+    def render(self, name, value, attrs=None, choices=(), serialization=SERIALIZATION_DEFAULT):
         if value is None: value = []
         final_attrs = self.build_attrs(attrs, name=name)
         output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)]
@@ -213,25 +214,26 @@
         self.choice_label = smart_unicode(choice[1])
         self.index = index
 
-    def __unicode__(self):
-        return u'<label>%s %s</label>' % (self.tag(), self.choice_label)
+    def __unicode__(self, serialization=SERIALIZATION_DEFAULT):
+        return u'<label>%s %s</label>' % (self.tag(serialization), self.choice_label)
 
     def is_checked(self):
         return self.value == self.choice_value
 
-    def tag(self):
+    def tag(self,serialization=SERIALIZATION_DEFAULT):
         if self.attrs.has_key('id'):
             self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)
         final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value)
         if self.is_checked():
             final_attrs['checked'] = 'checked'
-        return u'<input%s />' % flatatt(final_attrs)
+        return u'<input%s%s' % (flatatt(final_attrs),end_empty_element(u'input',serialization))
 
 class RadioFieldRenderer(StrAndUnicode):
     "An object used by RadioSelect to enable customization of radio widgets."
-    def __init__(self, name, value, attrs, choices):
+    def __init__(self, name, value, attrs, choices, serialization=SERIALIZATION_DEFAULT):
         self.name, self.value, self.attrs = name, value, attrs
         self.choices = choices
+        self.serialization = serialization;
 
     def __iter__(self):
         for i, choice in enumerate(self.choices):
@@ -241,17 +243,17 @@
         choice = self.choices[idx] # Let the IndexError propogate
         return RadioInput(self.name, self.value, self.attrs.copy(), choice, idx)
 
-    def __unicode__(self):
+    def __unicode__(self, serialization):
         "Outputs a <ul> for this set of radio fields."
         return u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' % w for w in self])
 
 class RadioSelect(Select):
-    def render(self, name, value, attrs=None, choices=()):
+    def render(self, name, value, attrs=None, choices=(), serialization=SERIALIZATION_DEFAULT):
         "Returns a RadioFieldRenderer instance rather than a Unicode string."
         if value is None: value = ''
         str_value = smart_unicode(value) # Normalize to string.
         attrs = attrs or {}
-        return RadioFieldRenderer(name, str_value, attrs, list(chain(self.choices, choices)))
+        return RadioFieldRenderer(name, str_value, attrs, list(chain(self.choices, choices)), serialization)
 
     def id_for_label(self, id_):
         # RadioSelect is represented by multiple <input type="radio"> fields,
@@ -264,7 +266,7 @@
     id_for_label = classmethod(id_for_label)
 
 class CheckboxSelectMultiple(SelectMultiple):
-    def render(self, name, value, attrs=None, choices=()):
+    def render(self, name, value, attrs=None, choices=(), serialization=SERIALIZATION_DEFAULT):
         if value is None: value = []
         has_id = attrs and attrs.has_key('id')
         final_attrs = self.build_attrs(attrs, name=name)
@@ -277,7 +279,7 @@
                 final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
             cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
             option_value = smart_unicode(option_value)
-            rendered_cb = cb.render(name, option_value)
+            rendered_cb = cb.render(name, option_value, serialization=serialization)
             output.append(u'<li><label>%s %s</label></li>' % (rendered_cb, escape(smart_unicode(option_label))))
         output.append(u'</ul>')
         return u'\n'.join(output)
@@ -311,7 +313,7 @@
         self.widgets = [isinstance(w, type) and w() or w for w in widgets]
         super(MultiWidget, self).__init__(attrs)
 
-    def render(self, name, value, attrs=None):
+    def render(self, name, value, attrs=None, serialization=SERIALIZATION_DEFAULT):
         # value is a list of values, each corresponding to a widget
         # in self.widgets.
         if not isinstance(value, list):
@@ -322,7 +324,7 @@
                 widget_value = value[i]
             except KeyError:
                 widget_value = None
-            output.append(widget.render(name + '_%s' % i, widget_value, attrs))
+            output.append(widget.render(name + '_%s' % i, widget_value, attrs, serialization))
         return self.format_output(output)
 
     def value_from_datadict(self, data, name):
