Commit ab686022 authored by Baptiste Mispelon's avatar Baptiste Mispelon Committed by Claude Paroz
Browse files

Fixed #20211: Document backwards-incompatible change in BoundField.label_tag

Also cleaned up label escaping and consolidated the test suite regarding
label_tag.
parent 0f99246b
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -519,7 +519,7 @@ class BoundField(object):

        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
        id_ = widget.attrs.get('id') or self.auto_id
        if id_:
@@ -527,6 +527,8 @@ class BoundField(object):
            contents = format_html('<label for="{0}"{1}>{2}</label>',
                                   widget.id_for_label(id_), attrs, contents
                                   )
        else:
            contents = conditional_escape(contents)
        return mark_safe(contents)

    def css_classes(self, extra_classes=None):
+4 −0
Original line number Diff line number Diff line
@@ -696,6 +696,10 @@ Miscellaneous
  longer. If you're using ``django.contrib.redirects``, make sure
  :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
==========================

+35 −17
Original line number Diff line number Diff line
@@ -1623,23 +1623,6 @@ class FormsTestCase(TestCase):
</form>""")
        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.,
        # 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
@@ -1828,3 +1811,38 @@ class FormsTestCase(TestCase):
        form = JSONForm(data={'json': '{}'});
        form.full_clean()
        self.assertEqual(form.cleaned_data, {'json' : {}})

    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;')