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.
This commit is contained in:
Claude Paroz 2013-05-25 15:18:48 +02:00
parent ab61dd2829
commit be0bab1bb8
3 changed files with 32 additions and 15 deletions

View File

@ -525,10 +525,11 @@ class BoundField(object):
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})
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)

View File

@ -11,8 +11,7 @@ from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
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 @@ class NestedObjectsTests(TestCase):
# 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 @@ class UtilTests(unittest.TestCase):
# 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,9 +298,9 @@ class UtilTests(unittest.TestCase):
cb = forms.BooleanField(label=mark_safe('<i>cb</i>'))
form = MyForm()
self.assertEqual(helpers.AdminField(form, 'text', is_first=False).label_tag(),
self.assertHTMLEqual(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(),
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
@ -310,9 +309,9 @@ class UtilTests(unittest.TestCase):
cb = forms.BooleanField(label='&cb')
form = MyForm()
self.assertEqual(helpers.AdminField(form, 'text', is_first=False).label_tag(),
self.assertHTMLEqual(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(),
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):

View File

@ -1846,3 +1846,20 @@ class FormsTestCase(TestCase):
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>')