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 = '