From 4c60c3edff4312303e1021fca47ed52c2152d285 Mon Sep 17 00:00:00 2001 From: David <smithdc@gmail.com> Date: Fri, 7 Jan 2022 07:46:55 +0000 Subject: [PATCH] Fixed #33419 -- Restored marking forms.Field.help_text as HTML safe. Regression in 456466d932830b096d39806e291fe23ec5ed38d5. Thanks Matt Westcott for the report. --- django/forms/jinja2/django/forms/p.html | 2 +- django/forms/jinja2/django/forms/table.html | 2 +- django/forms/jinja2/django/forms/ul.html | 2 +- django/forms/templates/django/forms/p.html | 2 +- .../forms/templates/django/forms/table.html | 2 +- django/forms/templates/django/forms/ul.html | 2 +- docs/releases/4.0.2.txt | 3 ++ tests/forms_tests/tests/test_forms.py | 35 +++++++++++++++++++ 8 files changed, 44 insertions(+), 6 deletions(-) diff --git a/django/forms/jinja2/django/forms/p.html b/django/forms/jinja2/django/forms/p.html index 999c4d963a..a2872d993e 100644 --- a/django/forms/jinja2/django/forms/p.html +++ b/django/forms/jinja2/django/forms/p.html @@ -8,7 +8,7 @@ {% if field.label %}{{ field.label_tag() }}{% endif %} {{ field }} {% if field.help_text %} - <span class="helptext">{{ field.help_text }}</span> + <span class="helptext">{{ field.help_text|safe }}</span> {% endif %} {% if loop.last %} {% for field in hidden_fields %}{{ field }}{% endfor %} diff --git a/django/forms/jinja2/django/forms/table.html b/django/forms/jinja2/django/forms/table.html index 92cd746a49..d1d51f2b12 100644 --- a/django/forms/jinja2/django/forms/table.html +++ b/django/forms/jinja2/django/forms/table.html @@ -16,7 +16,7 @@ {{ field }} {% if field.help_text %} <br> - <span class="helptext">{{ field.help_text }}</span> + <span class="helptext">{{ field.help_text|safe }}</span> {% endif %} {% if loop.last %} {% for field in hidden_fields %}{{ field }}{% endfor %} diff --git a/django/forms/jinja2/django/forms/ul.html b/django/forms/jinja2/django/forms/ul.html index 116a9b0808..cc4d893c0e 100644 --- a/django/forms/jinja2/django/forms/ul.html +++ b/django/forms/jinja2/django/forms/ul.html @@ -12,7 +12,7 @@ {% if field.label %}{{ field.label_tag() }}{% endif %} {{ field }} {% if field.help_text %} - <span class="helptext">{{ field.help_text }}</span> + <span class="helptext">{{ field.help_text|safe }}</span> {% endif %} {% if loop.last %} {% for field in hidden_fields %}{{ field }}{% endfor %} diff --git a/django/forms/templates/django/forms/p.html b/django/forms/templates/django/forms/p.html index 1835b7a461..1346937a34 100644 --- a/django/forms/templates/django/forms/p.html +++ b/django/forms/templates/django/forms/p.html @@ -8,7 +8,7 @@ {% if field.label %}{{ field.label_tag }}{% endif %} {{ field }} {% if field.help_text %} - <span class="helptext">{{ field.help_text }}</span> + <span class="helptext">{{ field.help_text|safe }}</span> {% endif %} {% if forloop.last %} {% for field in hidden_fields %}{{ field }}{% endfor %} diff --git a/django/forms/templates/django/forms/table.html b/django/forms/templates/django/forms/table.html index a553776f2f..d4aaafcf53 100644 --- a/django/forms/templates/django/forms/table.html +++ b/django/forms/templates/django/forms/table.html @@ -16,7 +16,7 @@ {{ field }} {% if field.help_text %} <br> - <span class="helptext">{{ field.help_text }}</span> + <span class="helptext">{{ field.help_text|safe }}</span> {% endif %} {% if forloop.last %} {% for field in hidden_fields %}{{ field }}{% endfor %} diff --git a/django/forms/templates/django/forms/ul.html b/django/forms/templates/django/forms/ul.html index 9ce6a49f07..ae38af6527 100644 --- a/django/forms/templates/django/forms/ul.html +++ b/django/forms/templates/django/forms/ul.html @@ -12,7 +12,7 @@ {% if field.label %}{{ field.label_tag }}{% endif %} {{ field }} {% if field.help_text %} - <span class="helptext">{{ field.help_text }}</span> + <span class="helptext">{{ field.help_text|safe }}</span> {% endif %} {% if forloop.last %} {% for field in hidden_fields %}{{ field }}{% endfor %} diff --git a/docs/releases/4.0.2.txt b/docs/releases/4.0.2.txt index b1f1fb9c76..21b1a56884 100644 --- a/docs/releases/4.0.2.txt +++ b/docs/releases/4.0.2.txt @@ -11,3 +11,6 @@ Bugfixes * Fixed a bug in Django 4.0 where ``TestCase.captureOnCommitCallbacks()`` could execute callbacks multiple times (:ticket:`33410`). + +* Fixed a regression in Django 4.0 where ``help_text`` was HTML-escaped in + automatically-generated forms (:ticket:`33419`). diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index 5c653fb492..aa47481998 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -2326,6 +2326,41 @@ Password: <input type="password" name="password" required> <input type="hidden" name="next" value="/"></li>""" ) + def test_help_text_html_safe(self): + """help_text should not be escaped.""" + class UserRegistration(Form): + username = CharField(max_length=10, help_text='e.g., user@example.com') + password = CharField( + widget=PasswordInput, + help_text='Help text is <strong>escaped</strong>.', + ) + + p = UserRegistration(auto_id=False) + self.assertHTMLEqual( + p.as_ul(), + '<li>Username: <input type="text" name="username" maxlength="10" required>' + '<span class="helptext">e.g., user@example.com</span></li>' + '<li>Password: <input type="password" name="password" required>' + '<span class="helptext">Help text is <strong>escaped</strong>.</span></li>' + ) + self.assertHTMLEqual( + p.as_p(), + '<p>Username: <input type="text" name="username" maxlength="10" required>' + '<span class="helptext">e.g., user@example.com</span></p>' + '<p>Password: <input type="password" name="password" required>' + '<span class="helptext">Help text is <strong>escaped</strong>.</span></p>' + ) + self.assertHTMLEqual( + p.as_table(), + '<tr><th>Username:</th><td>' + '<input type="text" name="username" maxlength="10" required><br>' + '<span class="helptext">e.g., user@example.com</span></td></tr>' + '<tr><th>Password:</th><td>' + '<input type="password" name="password" required><br>' + '<span class="helptext">Help text is <strong>escaped</strong>.</span>' + '</td></tr>' + ) + def test_subclassing_forms(self): # You can subclass a Form to add fields. The resulting form subclass will have # all of the fields of the parent Form, plus whichever fields you define in the