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 %} - {{ field.help_text }} + {{ field.help_text|safe }} {% 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 %}
- {{ field.help_text }} + {{ field.help_text|safe }} {% 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 %} - {{ field.help_text }} + {{ field.help_text|safe }} {% 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 %} - {{ field.help_text }} + {{ field.help_text|safe }} {% 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 %}
- {{ field.help_text }} + {{ field.help_text|safe }} {% 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 %} - {{ field.help_text }} + {{ field.help_text|safe }} {% 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 c478a71699..aa283d53c7 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -2252,6 +2252,41 @@ Password: """ ) + 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 escaped.', + ) + + p = UserRegistration(auto_id=False) + self.assertHTMLEqual( + p.as_ul(), + '
  • Username: ' + 'e.g., user@example.com
  • ' + '
  • Password: ' + 'Help text is escaped.
  • ' + ) + self.assertHTMLEqual( + p.as_p(), + '

    Username: ' + 'e.g., user@example.com

    ' + '

    Password: ' + 'Help text is escaped.

    ' + ) + self.assertHTMLEqual( + p.as_table(), + 'Username:' + '
    ' + 'e.g., user@example.com' + 'Password:' + '
    ' + 'Help text is escaped.' + '' + ) + 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