[1.5.x] Fixed #20211: Document backwards-incompatible change in BoundField.label_tag

Also cleaned up label escaping and consolidated the test suite regarding
label_tag.
Backport of ab686022f from master.
This commit is contained in:
Baptiste Mispelon 2013-04-06 16:04:30 +02:00 committed by Claude Paroz
parent 991432ee8a
commit 9c49e64b66
3 changed files with 42 additions and 18 deletions

View File

@ -503,7 +503,7 @@ class BoundField(object):
If attrs are given, they're used as HTML attributes on the <label> tag. If attrs are given, they're used as HTML attributes on the <label> tag.
""" """
contents = contents or conditional_escape(self.label) contents = contents or self.label
widget = self.field.widget widget = self.field.widget
id_ = widget.attrs.get('id') or self.auto_id id_ = widget.attrs.get('id') or self.auto_id
if id_: if id_:
@ -511,6 +511,8 @@ class BoundField(object):
contents = format_html('<label for="{0}"{1}>{2}</label>', contents = format_html('<label for="{0}"{1}>{2}</label>',
widget.id_for_label(id_), attrs, contents widget.id_for_label(id_), attrs, contents
) )
else:
contents = conditional_escape(contents)
return mark_safe(contents) return mark_safe(contents)
def css_classes(self, extra_classes=None): def css_classes(self, extra_classes=None):

View File

@ -697,6 +697,10 @@ Miscellaneous
longer. If you're using ``django.contrib.redirects``, make sure longer. If you're using ``django.contrib.redirects``, make sure
:setting:`INSTALLED_APPS` contains ``django.contrib.sites``. :setting:`INSTALLED_APPS` contains ``django.contrib.sites``.
* :meth:`BoundField.label_tag <django.forms.BoundField.label_tag>` now
escapes its ``contents`` argument. To avoid the HTML escaping, use
:func:`django.utils.safestring.mark_safe` on the argument before passing it.
Features deprecated in 1.5 Features deprecated in 1.5
========================== ==========================

View File

@ -1612,23 +1612,6 @@ class FormsTestCase(TestCase):
</form>""") </form>""")
self.assertEqual(Template('{{ form.password1.help_text }}').render(Context({'form': UserRegistration(auto_id=False)})), '') self.assertEqual(Template('{{ form.password1.help_text }}').render(Context({'form': UserRegistration(auto_id=False)})), '')
# The label_tag() method takes an optional attrs argument: a dictionary of HTML
# attributes to add to the <label> tag.
f = UserRegistration(auto_id='id_%s')
form_output = []
for bf in f:
form_output.append(bf.label_tag(attrs={'class': 'pretty'}))
expected_form_output = [
'<label for="id_username" class="pretty">Username</label>',
'<label for="id_password1" class="pretty">Password1</label>',
'<label for="id_password2" class="pretty">Password2</label>',
]
self.assertEqual(len(form_output), len(expected_form_output))
for i in range(len(form_output)):
self.assertHTMLEqual(form_output[i], expected_form_output[i])
# To display the errors that aren't associated with a particular field -- e.g., # To display the errors that aren't associated with a particular field -- e.g.,
# the errors caused by Form.clean() -- use {{ form.non_field_errors }} in the # the errors caused by Form.clean() -- use {{ form.non_field_errors }} in the
# template. If used on its own, it is displayed as a <ul> (or an empty string, if # template. If used on its own, it is displayed as a <ul> (or an empty string, if
@ -1797,3 +1780,38 @@ class FormsTestCase(TestCase):
form = NameForm(data={'name' : ['fname', 'lname']}) form = NameForm(data={'name' : ['fname', 'lname']})
self.assertTrue(form.is_valid()) self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data, {'name' : 'fname lname'}) self.assertEqual(form.cleaned_data, {'name' : 'fname lname'})
def test_boundfield_label_tag(self):
class SomeForm(Form):
field = CharField()
boundfield = SomeForm()['field']
testcases = [ # (args, kwargs, expected)
# without anything: just print the <label>
((), {}, '<label for="id_field">Field</label>'),
# passing just one argument: overrides the field's label
(('custom',), {}, '<label for="id_field">custom</label>'),
# the overriden label is escaped
(('custom&',), {}, '<label for="id_field">custom&amp;</label>'),
((mark_safe('custom&'),), {}, '<label for="id_field">custom&</label>'),
# Passing attrs to add extra attributes on the <label>
((), {'attrs': {'class': 'pretty'}}, '<label for="id_field" class="pretty">Field</label>')
]
for args, kwargs, expected in testcases:
self.assertHTMLEqual(boundfield.label_tag(*args, **kwargs), expected)
def test_boundfield_label_tag_no_id(self):
"""
If a widget has no id, label_tag just returns the text with no
surrounding <label>.
"""
class SomeForm(Form):
field = CharField()
boundfield = SomeForm(auto_id='')['field']
self.assertHTMLEqual(boundfield.label_tag(), 'Field')
self.assertHTMLEqual(boundfield.label_tag('Custom&'), 'Custom&amp;')