From d67a46e10459858b681176a3e1f8c6bca39d2ac7 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 31 Dec 2016 08:26:23 -0500 Subject: [PATCH] Refs #25135 -- Removed support for the contrib.admin allow_tags attribute. Per deprecation timeline. --- django/contrib/admin/helpers.py | 14 +-------- .../contrib/admin/templatetags/admin_list.py | 11 ------- docs/ref/contrib/admin/index.txt | 8 ----- docs/releases/2.0.txt | 3 ++ tests/admin_changelist/tests.py | 31 +------------------ tests/admin_views/admin.py | 6 +--- tests/admin_views/tests.py | 14 +-------- 7 files changed, 7 insertions(+), 80 deletions(-) diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index cbe03031a9..604fcd5b26 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import json -import warnings from django import forms from django.conf import settings @@ -14,7 +13,6 @@ from django.db.models.fields.related import ManyToManyRel from django.forms.utils import flatatt from django.template.defaultfilters import capfirst, linebreaksbr from django.utils import six -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.html import conditional_escape, format_html from django.utils.safestring import mark_safe @@ -218,17 +216,7 @@ class AdminReadonlyField(object): if hasattr(value, "__html__"): result_repr = value else: - result_repr = force_text(value) - if getattr(attr, "allow_tags", False): - warnings.warn( - "Deprecated allow_tags attribute used on %s. " - "Use django.utils.html.format_html(), format_html_join(), " - "or django.utils.safestring.mark_safe() instead." % attr, - RemovedInDjango20Warning - ) - result_repr = mark_safe(value) - else: - result_repr = linebreaksbr(result_repr) + result_repr = linebreaksbr(force_text(value)) else: if isinstance(f.remote_field, ManyToManyRel) and value is not None: result_repr = ", ".join(map(six.text_type, value.all())) diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index ce2a80cbc2..ad6c03ea89 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import datetime -import warnings from django.contrib.admin.templatetags.admin_urls import add_preserved_filters from django.contrib.admin.utils import ( @@ -18,7 +17,6 @@ from django.template.loader import get_template from django.templatetags.static import static from django.urls import NoReverseMatch from django.utils import formats -from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.safestring import mark_safe @@ -223,17 +221,8 @@ def items_for_result(cl, result, form): if f is None or f.auto_created: if field_name == 'action_checkbox': row_classes = ['action-checkbox'] - allow_tags = getattr(attr, 'allow_tags', False) boolean = getattr(attr, 'boolean', False) result_repr = display_for_value(value, empty_value_display, boolean) - if allow_tags: - warnings.warn( - "Deprecated allow_tags attribute used on field {}. " - "Use django.utils.html.format_html(), format_html_join(), " - "or django.utils.safestring.mark_safe() instead.".format(field_name), - RemovedInDjango20Warning - ) - result_repr = mark_safe(result_repr) if isinstance(value, (datetime.date, datetime.time)): row_classes.append('nowrap') else: diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 40acb7dd29..b08d17421e 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -633,14 +633,6 @@ subclass:: class PersonAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'colored_name') - .. deprecated:: 1.9 - - In older versions, you could add an ``allow_tags`` attribute to the - method to prevent auto-escaping. This attribute is deprecated as it's - safer to use :func:`~django.utils.html.format_html`, - :func:`~django.utils.html.format_html_join`, or - :func:`~django.utils.safestring.mark_safe` instead. - * As some examples have already demonstrated, when using a callable, a model method, or a ``ModelAdmin`` method, you can customize the column's title by adding a ``short_description`` attribute to the callable. diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index d1edbf6180..311a3d6da4 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -309,3 +309,6 @@ these features. * The ``callable_obj`` keyword argument to ``SimpleTestCase.assertRaisesMessage()`` is removed. + +* Support for the ``allow_tags`` attribute on ``ModelAdmin`` methods is + removed. diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index b2292a77a0..2f0f6ad46b 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -11,11 +11,10 @@ from django.contrib.admin.views.main import ALL_VAR, SEARCH_VAR, ChangeList from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from django.template import Context, Template -from django.test import TestCase, ignore_warnings, override_settings +from django.test import TestCase, override_settings from django.test.client import RequestFactory from django.urls import reverse from django.utils import formats, six -from django.utils.deprecation import RemovedInDjango20Warning from .admin import ( BandAdmin, ChildAdmin, ChordsBandAdmin, ConcertAdmin, @@ -253,34 +252,6 @@ class ChangeListTests(TestCase): with self.assertRaises(IncorrectLookupParameters): ChangeList(request, Child, *get_changelist_args(m)) - @ignore_warnings(category=RemovedInDjango20Warning) - def test_result_list_with_allow_tags(self): - """ - Test for deprecation of allow_tags attribute - """ - new_parent = Parent.objects.create(name='parent') - for i in range(2): - Child.objects.create(name='name %s' % i, parent=new_parent) - request = self.factory.get('/child/') - m = ChildAdmin(Child, custom_site) - - def custom_method(self, obj=None): - return 'Unsafe html
' - custom_method.allow_tags = True - - # Add custom method with allow_tags attribute - m.custom_method = custom_method - m.list_display = ['id', 'name', 'parent', 'custom_method'] - - cl = ChangeList(request, Child, *get_changelist_args(m)) - FormSet = m.get_changelist_formset(request) - cl.formset = FormSet(queryset=cl.result_list) - template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') - context = Context({'cl': cl}) - table_output = template.render(context) - custom_field_html = 'Unsafe html
' - self.assertInHTML(custom_field_html, table_output) - def test_custom_paginator(self): new_parent = Parent.objects.create(name='parent') for i in range(200): diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index e8a1cf3bff..d85f5de059 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -447,7 +447,7 @@ class PostAdmin(admin.ModelAdmin): readonly_fields = ( 'posted', 'awesomeness_level', 'coolness', 'value', 'multiline', 'multiline_html', lambda obj: "foo", - 'multiline_html_allow_tags', 'readonly_content', + 'readonly_content', ) inlines = [ @@ -470,10 +470,6 @@ class PostAdmin(admin.ModelAdmin): def multiline_html(self, instance): return mark_safe("Multiline
\nhtml
\ncontent") - def multiline_html_allow_tags(self, instance): - return "Multiline
html
content
with allow tags" - multiline_html_allow_tags.allow_tags = True - class FieldOverridePostForm(forms.ModelForm): model = FieldOverridePost diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index c952a9ebf2..a724d57559 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -35,9 +35,7 @@ from django.urls import NoReverseMatch, resolve, reverse from django.utils import formats, six, translation from django.utils._os import upath from django.utils.cache import get_max_age -from django.utils.deprecation import ( - RemovedInDjango20Warning, RemovedInDjango21Warning, -) +from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_bytes, force_text, iri_to_uri from django.utils.html import escape from django.utils.http import urlencode @@ -4655,7 +4653,6 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): def setUp(self): self.client.force_login(self.superuser) - @ignore_warnings(category=RemovedInDjango20Warning) # for allow_tags deprecation def test_readonly_get(self): response = self.client.get(reverse('admin:admin_views_post_add')) self.assertEqual(response.status_code, 200) @@ -4673,12 +4670,6 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): self.assertContains(response, 'Multiline
test
string') self.assertContains(response, '
Multiline
html
content
', html=True) self.assertContains(response, 'InlineMultiline
test
string') - # Remove only this last line when the deprecation completes. - self.assertContains( - response, - '
Multiline
html
content
with allow tags
', - html=True - ) self.assertContains(response, formats.localize(datetime.date.today() - datetime.timedelta(days=7))) @@ -4708,7 +4699,6 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): response = self.client.get(reverse('admin:admin_views_post_change', args=(p.pk,))) self.assertContains(response, "%d amount of cool" % p.pk) - @ignore_warnings(category=RemovedInDjango20Warning) # for allow_tags deprecation def test_readonly_text_field(self): p = Post.objects.create( title="Readonly test", content="test", @@ -4802,7 +4792,6 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): field = self.get_admin_readonly_field(response, 'plotdetails') self.assertEqual(field.contents(), '-') # default empty value - @ignore_warnings(category=RemovedInDjango20Warning) # for allow_tags deprecation def test_readonly_field_overrides(self): """ Regression test for #22087 - ModelForm Meta overrides are ignored by @@ -5148,7 +5137,6 @@ class CSSTest(TestCase): def setUp(self): self.client.force_login(self.superuser) - @ignore_warnings(category=RemovedInDjango20Warning) # for allow_tags deprecation def test_field_prefix_css_classes(self): """ Fields have a CSS class name with a 'field-' prefix.