summaryrefslogtreecommitdiff
path: root/tests/admin_filters
diff options
context:
space:
mode:
authorFederico Jaramillo Martínez <federicojaramillom@gmail.com>2018-01-05 23:53:51 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-01-03 07:58:04 +0100
commit372eaa395f167c038e546c6be554c96014d40109 (patch)
treec4809fba27079ace0bbfdba85e316af7f90e4c6c /tests/admin_filters
parent03f6159407600de8b98992e675c45bffde9fca5b (diff)
downloaddjango-372eaa395f167c038e546c6be554c96014d40109.tar.gz
Fixed #28991 -- Added EmptyFieldListFilter class in admin.filters.
Thanks Simon Charette and Carlton Gibson for reviews. Co-Authored-By: Jonas Haag <jonas@lophus.org> Co-Authored-By: Christophe Baldy <christophe.baldy@polyconseil.fr>
Diffstat (limited to 'tests/admin_filters')
-rw-r--r--tests/admin_filters/tests.py104
1 files changed, 102 insertions, 2 deletions
diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py
index 6db2147e51..75769085e0 100644
--- a/tests/admin_filters/tests.py
+++ b/tests/admin_filters/tests.py
@@ -3,8 +3,8 @@ import sys
import unittest
from django.contrib.admin import (
- AllValuesFieldListFilter, BooleanFieldListFilter, ModelAdmin,
- RelatedOnlyFieldListFilter, SimpleListFilter, site,
+ AllValuesFieldListFilter, BooleanFieldListFilter, EmptyFieldListFilter,
+ ModelAdmin, RelatedOnlyFieldListFilter, SimpleListFilter, site,
)
from django.contrib.admin.options import IncorrectLookupParameters
from django.contrib.auth.admin import UserAdmin
@@ -248,6 +248,17 @@ class BookmarkAdminGenericRelation(ModelAdmin):
list_filter = ['tags__tag']
+class BookAdminWithEmptyFieldListFilter(ModelAdmin):
+ list_filter = [
+ ('author', EmptyFieldListFilter),
+ ('title', EmptyFieldListFilter),
+ ]
+
+
+class DepartmentAdminWithEmptyFieldListFilter(ModelAdmin):
+ list_filter = [('description', EmptyFieldListFilter)]
+
+
class ListFiltersTests(TestCase):
request_factory = RequestFactory()
@@ -1374,3 +1385,92 @@ class ListFiltersTests(TestCase):
changelist = modeladmin.get_changelist_instance(request)
changelist.get_results(request)
self.assertEqual(changelist.full_result_count, 4)
+
+ def test_emptylistfieldfilter(self):
+ empty_description = Department.objects.create(code='EMPT', description='')
+ none_description = Department.objects.create(code='NONE', description=None)
+ empty_title = Book.objects.create(title='', author=self.alfred)
+
+ department_admin = DepartmentAdminWithEmptyFieldListFilter(Department, site)
+ book_admin = BookAdminWithEmptyFieldListFilter(Book, site)
+
+ tests = [
+ # Allows nulls and empty strings.
+ (
+ department_admin,
+ {'description__isempty': '1'},
+ [empty_description, none_description],
+ ),
+ (
+ department_admin,
+ {'description__isempty': '0'},
+ [self.dev, self.design],
+ ),
+ # Allows nulls.
+ (book_admin, {'author__isempty': '1'}, [self.guitar_book]),
+ (
+ book_admin,
+ {'author__isempty': '0'},
+ [self.django_book, self.bio_book, self.djangonaut_book, empty_title],
+ ),
+ # Allows empty strings.
+ (book_admin, {'title__isempty': '1'}, [empty_title]),
+ (
+ book_admin,
+ {'title__isempty': '0'},
+ [self.django_book, self.bio_book, self.djangonaut_book, self.guitar_book],
+ ),
+ ]
+ for modeladmin, query_string, expected_result in tests:
+ with self.subTest(
+ modeladmin=modeladmin.__class__.__name__,
+ query_string=query_string,
+ ):
+ request = self.request_factory.get('/', query_string)
+ request.user = self.alfred
+ changelist = modeladmin.get_changelist_instance(request)
+ queryset = changelist.get_queryset(request)
+ self.assertCountEqual(queryset, expected_result)
+
+ def test_emptylistfieldfilter_choices(self):
+ modeladmin = BookAdminWithEmptyFieldListFilter(Book, site)
+ request = self.request_factory.get('/')
+ request.user = self.alfred
+ changelist = modeladmin.get_changelist_instance(request)
+ filterspec = changelist.get_filters(request)[0][0]
+ self.assertEqual(filterspec.title, 'Verbose Author')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(len(choices), 3)
+
+ self.assertEqual(choices[0]['display'], 'All')
+ self.assertIs(choices[0]['selected'], True)
+ self.assertEqual(choices[0]['query_string'], '?')
+
+ self.assertEqual(choices[1]['display'], 'Empty')
+ self.assertIs(choices[1]['selected'], False)
+ self.assertEqual(choices[1]['query_string'], '?author__isempty=1')
+
+ self.assertEqual(choices[2]['display'], 'Not empty')
+ self.assertIs(choices[2]['selected'], False)
+ self.assertEqual(choices[2]['query_string'], '?author__isempty=0')
+
+ def test_emptylistfieldfilter_non_empty_field(self):
+ class EmployeeAdminWithEmptyFieldListFilter(ModelAdmin):
+ list_filter = [('department', EmptyFieldListFilter)]
+
+ modeladmin = EmployeeAdminWithEmptyFieldListFilter(Employee, site)
+ request = self.request_factory.get('/')
+ request.user = self.alfred
+ msg = (
+ "The list filter 'EmptyFieldListFilter' cannot be used with field "
+ "'department' which doesn't allow empty strings and nulls."
+ )
+ with self.assertRaisesMessage(ImproperlyConfigured, msg):
+ modeladmin.get_changelist_instance(request)
+
+ def test_emptylistfieldfilter_invalid_lookup_parameters(self):
+ modeladmin = BookAdminWithEmptyFieldListFilter(Book, site)
+ request = self.request_factory.get('/', {'author__isempty': 42})
+ request.user = self.alfred
+ with self.assertRaises(IncorrectLookupParameters):
+ modeladmin.get_changelist_instance(request)