From 182d25eb7a227206746bfa30aab13aaa34d1de84 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Tue, 10 Jan 2023 13:43:21 +0100 Subject: [PATCH] Refs #31026 -- Removed BaseForm._html_output() per deprecation timeline. --- django/forms/forms.py | 94 ------------ docs/releases/5.0.txt | 2 + .../tests/test_deprecation_forms.py | 135 +----------------- 3 files changed, 3 insertions(+), 228 deletions(-) diff --git a/django/forms/forms.py b/django/forms/forms.py index 6884e6e724..02ac26d9ae 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -13,7 +13,6 @@ from django.forms.widgets import Media, MediaDefiningClass from django.utils.datastructures import MultiValueDict from django.utils.deprecation import RemovedInDjango50Warning from django.utils.functional import cached_property -from django.utils.html import conditional_escape from django.utils.safestring import SafeString, mark_safe from django.utils.translation import gettext as _ @@ -219,99 +218,6 @@ class BaseForm(RenderableFormMixin): # widgets split data over several HTML fields. return widget.value_from_datadict(self.data, self.files, html_name) - def _html_output( - self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row - ): - "Output HTML. Used by as_table(), as_ul(), as_p()." - warnings.warn( - "django.forms.BaseForm._html_output() is deprecated. " - "Please use .render() and .get_context() instead.", - RemovedInDjango50Warning, - stacklevel=2, - ) - # Errors that should be displayed above all fields. - top_errors = self.non_field_errors().copy() - output, hidden_fields = [], [] - - for name, bf in self._bound_items(): - field = bf.field - html_class_attr = "" - bf_errors = self.error_class(bf.errors) - if bf.is_hidden: - if bf_errors: - top_errors.extend( - [ - _("(Hidden field %(name)s) %(error)s") - % {"name": name, "error": str(e)} - for e in bf_errors - ] - ) - hidden_fields.append(str(bf)) - else: - # Create a 'class="..."' attribute if the row should have any - # CSS classes applied. - css_classes = bf.css_classes() - if css_classes: - html_class_attr = ' class="%s"' % css_classes - - if errors_on_separate_row and bf_errors: - output.append(error_row % str(bf_errors)) - - if bf.label: - label = conditional_escape(bf.label) - label = bf.label_tag(label) or "" - else: - label = "" - - if field.help_text: - help_text = help_text_html % field.help_text - else: - help_text = "" - - output.append( - normal_row - % { - "errors": bf_errors, - "label": label, - "field": bf, - "help_text": help_text, - "html_class_attr": html_class_attr, - "css_classes": css_classes, - "field_name": bf.html_name, - } - ) - - if top_errors: - output.insert(0, error_row % top_errors) - - if hidden_fields: # Insert any hidden fields in the last row. - str_hidden = "".join(hidden_fields) - if output: - last_row = output[-1] - # Chop off the trailing row_ender (e.g. '') and - # insert the hidden fields. - if not last_row.endswith(row_ender): - # This can happen in the as_p() case (and possibly others - # that users write): if there are only top errors, we may - # not be able to conscript the last row for our purposes, - # so insert a new, empty row. - last_row = normal_row % { - "errors": "", - "label": "", - "field": "", - "help_text": "", - "html_class_attr": html_class_attr, - "css_classes": "", - "field_name": "", - } - output.append(last_row) - output[-1] = last_row[: -len(row_ender)] + str_hidden + row_ender - else: - # If there aren't any rows in the output, just append the - # hidden fields. - output.append(str_hidden) - return mark_safe("\n".join(output)) - @property def template_name(self): return self.renderer.form_template_name diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt index c1d6f25088..e3c1919072 100644 --- a/docs/releases/5.0.txt +++ b/docs/releases/5.0.txt @@ -297,6 +297,8 @@ to remove usage of these features. * The ``django.contrib.gis.admin.GeoModelAdmin`` and ``OSMGeoAdmin`` classes are removed. +* The undocumented ``BaseForm._html_output()`` method is removed. + See :ref:`deprecated-features-4.1` for details on these changes, including how to remove usage of these features. diff --git a/tests/forms_tests/tests/test_deprecation_forms.py b/tests/forms_tests/tests/test_deprecation_forms.py index 2a4fb6b0e1..dbc751bae8 100644 --- a/tests/forms_tests/tests/test_deprecation_forms.py +++ b/tests/forms_tests/tests/test_deprecation_forms.py @@ -1,11 +1,9 @@ # RemovedInDjango50 -from django.forms import CharField, EmailField, Form, HiddenInput +from django.forms import CharField, EmailField, Form from django.forms.utils import ErrorList from django.test import SimpleTestCase, ignore_warnings from django.utils.deprecation import RemovedInDjango50Warning -from .test_forms import Person - class DivErrorList(ErrorList): def __str__(self): @@ -20,21 +18,6 @@ class DivErrorList(ErrorList): class DeprecationTests(SimpleTestCase): - def test_deprecation_warning_html_output(self): - msg = ( - "django.forms.BaseForm._html_output() is deprecated. Please use " - ".render() and .get_context() instead." - ) - with self.assertRaisesMessage(RemovedInDjango50Warning, msg): - form = Person() - form._html_output( - normal_row='

', - error_row="%s", - row_ender="

", - help_text_html=" %s", - errors_on_separate_row=True, - ) - def test_deprecation_warning_error_list(self): class EmailForm(Form): email = EmailField() @@ -70,119 +53,3 @@ class DeprecatedTests(SimpleTestCase): '
This field is required.
' '

Comment:

', ) - - def test_field_name(self): - """#5749 - `field_name` may be used as a key in _html_output().""" - - class SomeForm(Form): - some_field = CharField() - - def as_p(self): - return self._html_output( - normal_row='

', - error_row="%s", - row_ender="

", - help_text_html=" %s", - errors_on_separate_row=True, - ) - - form = SomeForm() - self.assertHTMLEqual(form.as_p(), '

') - - def test_field_without_css_classes(self): - """ - `css_classes` may be used as a key in _html_output() (empty classes). - """ - - class SomeForm(Form): - some_field = CharField() - - def as_p(self): - return self._html_output( - normal_row='

', - error_row="%s", - row_ender="

", - help_text_html=" %s", - errors_on_separate_row=True, - ) - - form = SomeForm() - self.assertHTMLEqual(form.as_p(), '

') - - def test_field_with_css_class(self): - """ - `css_classes` may be used as a key in _html_output() (class comes - from required_css_class in this case). - """ - - class SomeForm(Form): - some_field = CharField() - required_css_class = "foo" - - def as_p(self): - return self._html_output( - normal_row='

', - error_row="%s", - row_ender="

", - help_text_html=" %s", - errors_on_separate_row=True, - ) - - form = SomeForm() - self.assertHTMLEqual(form.as_p(), '

') - - def test_field_name_with_hidden_input(self): - """ - BaseForm._html_output() should merge all the hidden input fields and - put them in the last row. - """ - - class SomeForm(Form): - hidden1 = CharField(widget=HiddenInput) - custom = CharField() - hidden2 = CharField(widget=HiddenInput) - - def as_p(self): - return self._html_output( - normal_row="%(field)s %(field_name)s

", - error_row="%s", - row_ender="

", - help_text_html=" %s", - errors_on_separate_row=True, - ) - - form = SomeForm() - self.assertHTMLEqual( - form.as_p(), - '

custom' - '' - '

', - ) - - def test_field_name_with_hidden_input_and_non_matching_row_ender(self): - """ - BaseForm._html_output() should merge all the hidden input fields and - put them in the last row ended with the specific row ender. - """ - - class SomeForm(Form): - hidden1 = CharField(widget=HiddenInput) - custom = CharField() - hidden2 = CharField(widget=HiddenInput) - - def as_p(self): - return self._html_output( - normal_row="%(field)s %(field_name)s

", - error_row="%s", - row_ender="

", - help_text_html=" %s", - errors_on_separate_row=True, - ) - - form = SomeForm() - self.assertHTMLEqual( - form.as_p(), - '

custom

\n' - '' - '

', - )