Index: django/newforms/widgets.py
===================================================================
--- django/newforms/widgets.py	(revision 6862)
+++ django/newforms/widgets.py	(working copy)
@@ -367,8 +367,9 @@
             cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
             option_value = force_unicode(option_value)
             rendered_cb = cb.render(name, option_value)
-            output.append(u'<li><label>%s %s</label></li>' % (rendered_cb,
-                    conditional_escape(force_unicode(option_label))))
+            for_id = final_attrs.get('id', option_value)
+            output.append(u'<li>%s <label for="%s">%s</label></li>' % (rendered_cb, for_id, conditional_escape(force_unicode(option_label))))
         output.append(u'</ul>')
         return mark_safe(u'\n'.join(output))
 
Index: tests/regressiontests/forms/forms.py
===================================================================
--- tests/regressiontests/forms/forms.py	(revision 6862)
+++ tests/regressiontests/forms/forms.py	(working copy)
@@ -494,20 +494,20 @@
 >>> f = SongForm(auto_id=False)
 >>> print f['composers']
 <ul>
-<li><label><input type="checkbox" name="composers" value="J" /> John Lennon</label></li>
-<li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
+<li><input type="checkbox" name="composers" value="J" /> <label for="J">John Lennon</label></li>
+<li><input type="checkbox" name="composers" value="P" /> <label for="P">Paul McCartney</label></li>
 </ul>
 >>> f = SongForm({'composers': ['J']}, auto_id=False)
 >>> print f['composers']
 <ul>
-<li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li>
-<li><label><input type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
+<li><input checked="checked" type="checkbox" name="composers" value="J" /> <label for="J">John Lennon</label></li>
+<li><input type="checkbox" name="composers" value="P" /> <label for="P">Paul McCartney</label></li>
 </ul>
 >>> f = SongForm({'composers': ['J', 'P']}, auto_id=False)
 >>> print f['composers']
 <ul>
-<li><label><input checked="checked" type="checkbox" name="composers" value="J" /> John Lennon</label></li>
-<li><label><input checked="checked" type="checkbox" name="composers" value="P" /> Paul McCartney</label></li>
+<li><input checked="checked" type="checkbox" name="composers" value="J" /> <label for="J">John Lennon</label></li>
+<li><input checked="checked" type="checkbox" name="composers" value="P" /> <label for="P">Paul McCartney</label></li>
 </ul>
 
 Regarding auto_id, CheckboxSelectMultiple is a special case. Each checkbox
@@ -516,8 +516,8 @@
 >>> f = SongForm(auto_id='%s_id')
 >>> print f['composers']
 <ul>
-<li><label><input type="checkbox" name="composers" value="J" id="composers_id_0" /> John Lennon</label></li>
-<li><label><input type="checkbox" name="composers" value="P" id="composers_id_1" /> Paul McCartney</label></li>
+<li><input type="checkbox" name="composers" value="J" id="composers_id_0" /> <label for="composers_id_0">John Lennon</label></li>
+<li><input type="checkbox" name="composers" value="P" id="composers_id_1" /> <label for="composers_id_1">Paul McCartney</label></li>
 </ul>
 
 Data for a MultipleChoiceField should be a list. QueryDict and MultiValueDict
Index: tests/regressiontests/forms/widgets.py
===================================================================
--- tests/regressiontests/forms/widgets.py	(revision 6862)
+++ tests/regressiontests/forms/widgets.py	(working copy)
@@ -762,71 +762,71 @@
 >>> w = CheckboxSelectMultiple()
 >>> print w.render('beatles', ['J'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
 <ul>
-<li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li>
-<li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li>
-<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
-<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
+<li><input checked="checked" type="checkbox" name="beatles" value="J" /> <label for="J">John</label></li>
+<li><input type="checkbox" name="beatles" value="P" /> <label for="P">Paul</label></li>
+<li><input type="checkbox" name="beatles" value="G" /> <label for="G">George</label></li>
+<li><input type="checkbox" name="beatles" value="R" /> <label for="R">Ringo</label></li>
 </ul>
 >>> print w.render('beatles', ['J', 'P'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
 <ul>
-<li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li>
-<li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li>
-<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
-<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
+<li><input checked="checked" type="checkbox" name="beatles" value="J" /> <label for="J">John</label></li>
+<li><input checked="checked" type="checkbox" name="beatles" value="P" /> <label for="P">Paul</label></li>
+<li><input type="checkbox" name="beatles" value="G" /> <label for="G">George</label></li>
+<li><input type="checkbox" name="beatles" value="R" /> <label for="R">Ringo</label></li>
 </ul>
 >>> print w.render('beatles', ['J', 'P', 'R'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
 <ul>
-<li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li>
-<li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li>
-<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
-<li><label><input checked="checked" type="checkbox" name="beatles" value="R" /> Ringo</label></li>
+<li><input checked="checked" type="checkbox" name="beatles" value="J" /> <label for="J">John</label></li>
+<li><input checked="checked" type="checkbox" name="beatles" value="P" /> <label for="P">Paul</label></li>
+<li><input type="checkbox" name="beatles" value="G" /> <label for="G">George</label></li>
+<li><input checked="checked" type="checkbox" name="beatles" value="R" /> <label for="R">Ringo</label></li>
 </ul>
 
 If the value is None, none of the options are selected:
 >>> print w.render('beatles', None, choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
 <ul>
-<li><label><input type="checkbox" name="beatles" value="J" /> John</label></li>
-<li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li>
-<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
-<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
+<li><input type="checkbox" name="beatles" value="J" /> <label for="J">John</label></li>
+<li><input type="checkbox" name="beatles" value="P" /> <label for="P">Paul</label></li>
+<li><input type="checkbox" name="beatles" value="G" /> <label for="G">George</label></li>
+<li><input type="checkbox" name="beatles" value="R" /> <label for="R">Ringo</label></li>
 </ul>
 
 If the value corresponds to a label (but not to an option value), none of the options are selected:
 >>> print w.render('beatles', ['John'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
 <ul>
-<li><label><input type="checkbox" name="beatles" value="J" /> John</label></li>
-<li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li>
-<li><label><input type="checkbox" name="beatles" value="G" /> George</label></li>
-<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
+<li><input type="checkbox" name="beatles" value="J" /> <label for="J">John</label></li>
+<li><input type="checkbox" name="beatles" value="P" /> <label for="P">Paul</label></li>
+<li><input type="checkbox" name="beatles" value="G" /> <label for="G">George</label></li>
+<li><input type="checkbox" name="beatles" value="R" /> <label for="R">Ringo</label></li>
 </ul>
 
 If multiple values are given, but some of them are not valid, the valid ones are selected:
 >>> print w.render('beatles', ['J', 'G', 'foo'], choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
 <ul>
-<li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li>
-<li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li>
-<li><label><input checked="checked" type="checkbox" name="beatles" value="G" /> George</label></li>
-<li><label><input type="checkbox" name="beatles" value="R" /> Ringo</label></li>
+<li><input checked="checked" type="checkbox" name="beatles" value="J" /> <label for="J">John</label></li>
+<li><input type="checkbox" name="beatles" value="P" /> <label for="P">Paul</label></li>
+<li><input checked="checked" type="checkbox" name="beatles" value="G" /> <label for="G">George</label></li>
+<li><input type="checkbox" name="beatles" value="R" /> <label for="R">Ringo</label></li>
 </ul>
 
 The value is compared to its str():
 >>> print w.render('nums', [2], choices=[('1', '1'), ('2', '2'), ('3', '3')])
 <ul>
-<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
-<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
-<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
+<li><input type="checkbox" name="nums" value="1" /> <label for="1">1</label></li>
+<li><input checked="checked" type="checkbox" name="nums" value="2" /> <label for="2">2</label></li>
+<li><input type="checkbox" name="nums" value="3" /> <label for="3">3</label></li>
 </ul>
 >>> print w.render('nums', ['2'], choices=[(1, 1), (2, 2), (3, 3)])
 <ul>
-<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
-<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
-<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
+<li><input type="checkbox" name="nums" value="1" /> <label for="1">1</label></li>
+<li><input checked="checked" type="checkbox" name="nums" value="2" /> <label for="2">2</label></li>
+<li><input type="checkbox" name="nums" value="3" /> <label for="3">3</label></li>
 </ul>
 >>> print w.render('nums', [2], choices=[(1, 1), (2, 2), (3, 3)])
 <ul>
-<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
-<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
-<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
+<li><input type="checkbox" name="nums" value="1" /> <label for="1">1</label></li>
+<li><input checked="checked" type="checkbox" name="nums" value="2" /> <label for="2">2</label></li>
+<li><input type="checkbox" name="nums" value="3" /> <label for="3">3</label></li>
 </ul>
 
 The 'choices' argument can be any iterable:
@@ -835,45 +835,45 @@
 ...         yield (i, i)
 >>> print w.render('nums', [2], choices=get_choices())
 <ul>
-<li><label><input type="checkbox" name="nums" value="0" /> 0</label></li>
-<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
-<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
-<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
-<li><label><input type="checkbox" name="nums" value="4" /> 4</label></li>
+<li><input type="checkbox" name="nums" value="0" /> <label for="0">0</label></li>
+<li><input type="checkbox" name="nums" value="1" /> <label for="1">1</label></li>
+<li><input checked="checked" type="checkbox" name="nums" value="2" /> <label for="2">2</label></li>
+<li><input type="checkbox" name="nums" value="3" /> <label for="3">3</label></li>
+<li><input type="checkbox" name="nums" value="4" /> <label for="4">4</label></li>
 </ul>
 
 You can also pass 'choices' to the constructor:
 >>> w = CheckboxSelectMultiple(choices=[(1, 1), (2, 2), (3, 3)])
 >>> print w.render('nums', [2])
 <ul>
-<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
-<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
-<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
+<li><input type="checkbox" name="nums" value="1" /> <label for="1">1</label></li>
+<li><input checked="checked" type="checkbox" name="nums" value="2" /> <label for="2">2</label></li>
+<li><input type="checkbox" name="nums" value="3" /> <label for="3">3</label></li>
 </ul>
 
 If 'choices' is passed to both the constructor and render(), then they'll both be in the output:
 >>> print w.render('nums', [2], choices=[(4, 4), (5, 5)])
 <ul>
-<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>
-<li><label><input checked="checked" type="checkbox" name="nums" value="2" /> 2</label></li>
-<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>
-<li><label><input type="checkbox" name="nums" value="4" /> 4</label></li>
-<li><label><input type="checkbox" name="nums" value="5" /> 5</label></li>
+<li><input type="checkbox" name="nums" value="1" /> <label for="1">1</label></li>
+<li><input checked="checked" type="checkbox" name="nums" value="2" /> <label for="2">2</label></li>
+<li><input type="checkbox" name="nums" value="3" /> <label for="3">3</label></li>
+<li><input type="checkbox" name="nums" value="4" /> <label for="4">4</label></li>
+<li><input type="checkbox" name="nums" value="5" /> <label for="5">5</label></li>
 </ul>
 
 # Choices are escaped correctly
 >>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you &gt; me'))))
 <ul>
-<li><label><input type="checkbox" name="escape" value="1" /> 1</label></li>
-<li><label><input type="checkbox" name="escape" value="2" /> 2</label></li>
-<li><label><input type="checkbox" name="escape" value="3" /> 3</label></li>
-<li><label><input type="checkbox" name="escape" value="bad" /> you &amp; me</label></li>
-<li><label><input type="checkbox" name="escape" value="good" /> you &gt; me</label></li>
+<li><input type="checkbox" name="escape" value="1" /> <label for="1">1</label></li>
+<li><input type="checkbox" name="escape" value="2" /> <label for="2">2</label></li>
+<li><input type="checkbox" name="escape" value="3" /> <label for="3">3</label></li>
+<li><input type="checkbox" name="escape" value="bad" /> <label for="bad">you &amp; me</label></li>
+<li><input type="checkbox" name="escape" value="good" /> <label for="good">you &gt; me</label></li>
 </ul>
 
 # Unicode choices are correctly rendered as HTML
 >>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])
-u'<ul>\n<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>\n<li><label><input type="checkbox" name="nums" value="2" /> 2</label></li>\n<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>\n<li><label><input checked="checked" type="checkbox" name="nums" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="checkbox" name="nums" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
+u'<ul>\n<li><input type="checkbox" name="nums" value="1" /> <label for="1">1</label></li>\n<li><input type="checkbox" name="nums" value="2" /> <label for="2">2</label></li>\n<li><input type="checkbox" name="nums" value="3" /> <label for="3">3</label></li>\n<li><input checked="checked" type="checkbox" name="nums" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> <label for="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><input type="checkbox" name="nums" value="\u0107\u017e\u0161\u0111" /> <label for="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'
 
 # MultiWidget #################################################################
 
