diff --git a/django/contrib/admin/static/admin/css/changelists.css b/django/contrib/admin/static/admin/css/changelists.css index 30a6386a31..3eefd00fb1 100644 --- a/django/contrib/admin/static/admin/css/changelists.css +++ b/django/contrib/admin/static/admin/css/changelists.css @@ -187,6 +187,12 @@ color: #036; } +#changelist-filter #changelist-filter-clear a { + font-size: 13px; + padding-bottom: 10px; + border-bottom: 1px solid #eaeaea; +} + /* DATE DRILLDOWN */ .change-list ul.toplinks { diff --git a/django/contrib/admin/templates/admin/change_list.html b/django/contrib/admin/templates/admin/change_list.html index 8b275362af..4dc9ed52d7 100644 --- a/django/contrib/admin/templates/admin/change_list.html +++ b/django/contrib/admin/templates/admin/change_list.html @@ -60,6 +60,11 @@ {% if cl.has_filters %}

{% translate 'Filter' %}

+ {% if cl.has_filters or cl.search_fields %} + {% if cl.preserved_filters %}

+ ✖ {% translate "Clear all filters" %} +

{% endif %} + {% endif %} {% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
{% endif %} diff --git a/docs/releases/3.1.txt b/docs/releases/3.1.txt index ced98c2e47..709c3917bc 100644 --- a/docs/releases/3.1.txt +++ b/docs/releases/3.1.txt @@ -37,6 +37,9 @@ Minor features :attr:`.ModelAdmin.list_filter` allows filtering on empty values (empty strings and nulls) in the admin changelist view. +* Filters in the right sidebar of the admin changelist view now contains a link + to clear all filters. + :mod:`django.contrib.admindocs` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index 8cb6f7eff9..933d2ac1d2 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -707,6 +707,18 @@ class ChangeListTests(TestCase): link = reverse('admin:admin_changelist_parent_change', args=(p.pk,)) self.assertNotContains(response, '' % link) + def test_clear_all_filters_link(self): + self.client.force_login(self.superuser) + link = '✖ Clear all filters' + response = self.client.get(reverse('admin:auth_user_changelist')) + self.assertNotContains(response, link) + for data in ( + {SEARCH_VAR: 'test'}, + {'is_staff__exact': '0'}, + ): + response = self.client.get(reverse('admin:auth_user_changelist'), data=data) + self.assertContains(response, link) + def test_tuple_list_display(self): swallow = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2') swallow2 = Swallow.objects.create(origin='Africa', load='12.34', speed='22.2')