Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #11725 -- Made possible to create widget label tag without "for"

Thanks Denis Martinez for the report and initial patch, and
Sergey Kolosov for bringing the patch up to date.
  • Loading branch information...
commit be0bab1bb8da80402248cd1fa22fd4cc09b34fe7 1 parent ab61dd2
Claude Paroz claudep authored
7 django/forms/forms.py
View
@@ -525,10 +525,11 @@ def label_tag(self, contents=None, attrs=None):
widget = self.field.widget
id_ = widget.attrs.get('id') or self.auto_id
if id_:
+ id_for_label = widget.id_for_label(id_)
+ if id_for_label:
+ attrs = dict(attrs or {}, **{'for': id_for_label})
Simon Charette Collaborator

for=id_for_label would have worked here.

Claude Paroz Collaborator
claudep added a note

He, he, try and you'll see :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
attrs = flatatt(attrs) if attrs else ''
- contents = format_html('<label for="{0}"{1}>{2}</label>',
- widget.id_for_label(id_), attrs, contents
- )
+ contents = format_html('<label{0}>{1}</label>', attrs, contents)
else:
contents = conditional_escape(contents)
return mark_safe(contents)
23 tests/admin_util/tests.py
View
@@ -11,8 +11,7 @@
from django.contrib.sites.models import Site
from django.db import models, DEFAULT_DB_ALIAS
from django import forms
-from django.test import TestCase
-from django.utils import unittest
+from django.test import SimpleTestCase, TestCase
from django.utils.formats import localize
from django.utils.safestring import mark_safe
from django.utils import six
@@ -82,7 +81,7 @@ def test_on_delete_do_nothing(self):
# One for Location, one for Guest, and no query for EventGuide
n.collect(objs)
-class UtilTests(unittest.TestCase):
+class UtilTests(SimpleTestCase):
def test_values_from_lookup_field(self):
"""
Regression test for #12654: lookup_field
@@ -151,7 +150,7 @@ def test_null_display_for_field(self):
# handling.
display_value = display_for_field(None, models.NullBooleanField())
expected = '<img src="%sadmin/img/icon-unknown.gif" alt="None" />' % settings.STATIC_URL
- self.assertEqual(display_value, expected)
+ self.assertHTMLEqual(display_value, expected)
display_value = display_for_field(None, models.DecimalField())
self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE)
@@ -299,10 +298,10 @@ class MyForm(forms.Form):
cb = forms.BooleanField(label=mark_safe('<i>cb</i>'))
form = MyForm()
- self.assertEqual(helpers.AdminField(form, 'text', is_first=False).label_tag(),
- '<label for="id_text" class="required inline"><i>text</i>:</label>')
- self.assertEqual(helpers.AdminField(form, 'cb', is_first=False).label_tag(),
- '<label for="id_cb" class="vCheckboxLabel required inline"><i>cb</i></label>')
+ self.assertHTMLEqual(helpers.AdminField(form, 'text', is_first=False).label_tag(),
+ '<label for="id_text" class="required inline"><i>text</i>:</label>')
+ self.assertHTMLEqual(helpers.AdminField(form, 'cb', is_first=False).label_tag(),
+ '<label for="id_cb" class="vCheckboxLabel required inline"><i>cb</i></label>')
# normal strings needs to be escaped
class MyForm(forms.Form):
@@ -310,10 +309,10 @@ class MyForm(forms.Form):
cb = forms.BooleanField(label='&cb')
form = MyForm()
- self.assertEqual(helpers.AdminField(form, 'text', is_first=False).label_tag(),
- '<label for="id_text" class="required inline">&amp;text:</label>')
- self.assertEqual(helpers.AdminField(form, 'cb', is_first=False).label_tag(),
- '<label for="id_cb" class="vCheckboxLabel required inline">&amp;cb</label>')
+ self.assertHTMLEqual(helpers.AdminField(form, 'text', is_first=False).label_tag(),
+ '<label for="id_text" class="required inline">&amp;text:</label>')
+ self.assertHTMLEqual(helpers.AdminField(form, 'cb', is_first=False).label_tag(),
+ '<label for="id_cb" class="vCheckboxLabel required inline">&amp;cb</label>')
def test_flatten_fieldsets(self):
"""
17 tests/forms_tests/tests/test_forms.py
View
@@ -1846,3 +1846,20 @@ class SomeForm(Form):
self.assertHTMLEqual(boundfield.label_tag(), 'Field')
self.assertHTMLEqual(boundfield.label_tag('Custom&'), 'Custom&amp;')
+
+ def test_boundfield_label_tag_custom_widget_id_for_label(self):
+ class CustomIdForLabelTextInput(TextInput):
+ def id_for_label(self, id):
+ return 'custom_' + id
+
+ class EmptyIdForLabelTextInput(TextInput):
+ def id_for_label(self, id):
+ return None
+
+ class SomeForm(Form):
+ custom = CharField(widget=CustomIdForLabelTextInput)
+ empty = CharField(widget=EmptyIdForLabelTextInput)
+
+ form = SomeForm()
+ self.assertHTMLEqual(form['custom'].label_tag(), '<label for="custom_id_custom">Custom</label>')
+ self.assertHTMLEqual(form['empty'].label_tag(), '<label>Empty</label>')
Simon Charette

for=id_for_label would have worked here.

Claude Paroz

He, he, try and you'll see :-)

Please sign in to comment.
Something went wrong with that request. Please try again.