Index: django/newforms/widgets.py
===================================================================
--- django/newforms/widgets.py	(revision 6884)
+++ django/newforms/widgets.py	(working copy)
@@ -281,16 +281,20 @@
         self.index = index
 
     def __unicode__(self):
-        return mark_safe(u'<label>%s %s</label>' % (self.tag(),
+        if 'id' in self.attrs:
+            for_attr = ' for="%s_%s"' % (self.attrs['id'], self.index)
+        else:
+            for_attr = ''
+        return mark_safe(u'<label%s>%s %s</label>' % (for_attr, self.tag(),
                 conditional_escape(force_unicode(self.choice_label))))
 
     def is_checked(self):
         return self.value == self.choice_value
 
     def tag(self):
+        final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value)
         if 'id' in self.attrs:
-            self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)
-        final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value)
+            final_attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)
         if self.is_checked():
             final_attrs['checked'] = 'checked'
         return mark_safe(u'<input%s />' % flatatt(final_attrs))
@@ -364,10 +368,13 @@
             # so that the checkboxes don't all have the same ID attribute.
             if has_id:
                 final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
+                for_attr = ' for="%s_%s"' % (attrs['id'], i)
+            else:
+                for_attr = ''
             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,
+            output.append(u'<li><label%s>%s %s</label></li>' % (for_attr, rendered_cb,
                     conditional_escape(force_unicode(option_label))))
         output.append(u'</ul>')
         return mark_safe(u'\n'.join(output))
Index: tests/regressiontests/forms/regressions.py
===================================================================
--- tests/regressiontests/forms/regressions.py	(revision 6884)
+++ tests/regressiontests/forms/regressions.py	(working copy)
@@ -40,7 +40,7 @@
 ...     somechoice = ChoiceField(choices=GENDERS, widget=RadioSelect(), label=u'\xc5\xf8\xdf')
 >>> f = SomeForm()
 >>> f.as_p()
-u'<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label> <ul>\n<li><label><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label><input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" /> Nainen</label></li>\n</ul></p>'
+u'<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label> <ul>\n<li><label for="id_somechoice_0"><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label for="id_somechoice_1"><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label for="id_somechoice_2"><input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" /> Nainen</label></li>\n</ul></p>'
 
 Testing choice validation with UTF-8 bytestrings as input (these are the
 Russian abbreviations "мес." and "шт.".
@@ -56,7 +56,7 @@
 >>> activate('ru')
 >>> f = SomeForm({})
 >>> f.as_p()
-u'<ul class="errorlist"><li>\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435.</li></ul>\n<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label> <ul>\n<li><label><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label><input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" /> Nainen</label></li>\n</ul></p>'
+u'<ul class="errorlist"><li>\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u0435.</li></ul>\n<p><label for="id_somechoice_0">\xc5\xf8\xdf:</label> <ul>\n<li><label for="id_somechoice_0"><input type="radio" id="id_somechoice_0" value="\xc5" name="somechoice" /> En tied\xe4</label></li>\n<li><label for="id_somechoice_1"><input type="radio" id="id_somechoice_1" value="\xf8" name="somechoice" /> Mies</label></li>\n<li><label for="id_somechoice_2"><input type="radio" id="id_somechoice_2" value="\xdf" name="somechoice" /> Nainen</label></li>\n</ul></p>'
 >>> deactivate()
 
 Deep copying translated text shouldn't raise an error
Index: tests/regressiontests/forms/forms.py
===================================================================
--- tests/regressiontests/forms/forms.py	(revision 6884)
+++ tests/regressiontests/forms/forms.py	(working copy)
@@ -424,8 +424,8 @@
 >>> f = FrameworkForm(auto_id='id_%s')
 >>> print f['language']
 <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>
+<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
+<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
 </ul>
 
 When RadioSelect is used with auto_id, and the whole form is printed using
@@ -434,20 +434,20 @@
 >>> 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>
-<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>
+<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
+<li><label for="id_language_1"><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><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>
+<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
+<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
 </ul></li>
 >>> print f.as_p()
 <p><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p>
 <p><label for="id_language_0">Language:</label> <ul>
-<li><label><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
-<li><label><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
+<li><label for="id_language_0"><input type="radio" id="id_language_0" value="P" name="language" /> Python</label></li>
+<li><label for="id_language_1"><input type="radio" id="id_language_1" value="J" name="language" /> Java</label></li>
 </ul></p>
 
 MultipleChoiceField is a special case, as its data is required to be a list:
@@ -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><label for="composers_id_0"><input type="checkbox" name="composers" value="J" id="composers_id_0" /> John Lennon</label></li>
+<li><label for="composers_id_1"><input type="checkbox" name="composers" value="P" id="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 6884)
+++ tests/regressiontests/forms/widgets.py	(working copy)
@@ -741,20 +741,20 @@
 >>> w = RadioSelect(attrs={'id':'foo'})
 >>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')))
 <ul>
-<li><label><input checked="checked" type="radio" id="foo_0" value="J" name="beatle" /> John</label></li>
-<li><label><input type="radio" id="foo_1" value="P" name="beatle" /> Paul</label></li>
-<li><label><input type="radio" id="foo_2" value="G" name="beatle" /> George</label></li>
-<li><label><input type="radio" id="foo_3" value="R" name="beatle" /> Ringo</label></li>
+<li><label for="foo_0"><input checked="checked" type="radio" id="foo_0" value="J" name="beatle" /> John</label></li>
+<li><label for="foo_1"><input type="radio" id="foo_1" value="P" name="beatle" /> Paul</label></li>
+<li><label for="foo_2"><input type="radio" id="foo_2" value="G" name="beatle" /> George</label></li>
+<li><label for="foo_3"><input type="radio" id="foo_3" value="R" name="beatle" /> Ringo</label></li>
 </ul>
 
 # Attributes provided at render-time are passed to the constituent inputs
 >>> w = RadioSelect()
 >>> print w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), attrs={'id':'bar'})
 <ul>
-<li><label><input checked="checked" type="radio" id="bar_0" value="J" name="beatle" /> John</label></li>
-<li><label><input type="radio" id="bar_1" value="P" name="beatle" /> Paul</label></li>
-<li><label><input type="radio" id="bar_2" value="G" name="beatle" /> George</label></li>
-<li><label><input type="radio" id="bar_3" value="R" name="beatle" /> Ringo</label></li>
+<li><label for="bar_0"><input checked="checked" type="radio" id="bar_0" value="J" name="beatle" /> John</label></li>
+<li><label for="bar_1"><input type="radio" id="bar_1" value="P" name="beatle" /> Paul</label></li>
+<li><label for="bar_2"><input type="radio" id="bar_2" value="G" name="beatle" /> George</label></li>
+<li><label for="bar_3"><input type="radio" id="bar_3" value="R" name="beatle" /> Ringo</label></li>
 </ul>
 
 # CheckboxSelectMultiple Widget ###############################################
