summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJannis Leidel <jannis@leidel.info>2011-05-03 10:44:23 +0000
committerJannis Leidel <jannis@leidel.info>2011-05-03 10:44:23 +0000
commit18d2f4a81611fa4051ccdcfb9dd443f3a247102e (patch)
tree86aafec1f0835166a33b84285de6166b03b7bf30 /tests
parenta85cd1688b7a4468a4836b892f35480dc16ad331 (diff)
Fixed #5833 -- Modified the admin list filters to be easier to customize. Many thanks to Honza Král, Tom X. Tobin, gerdemb, eandre, sciyoshi, bendavis78 and Julien Phalip for working on this.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16144 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
-rw-r--r--tests/regressiontests/admin_filters/__init__.py (renamed from tests/regressiontests/admin_filterspecs/__init__.py)0
-rw-r--r--tests/regressiontests/admin_filters/models.py (renamed from tests/regressiontests/admin_filterspecs/models.py)16
-rw-r--r--tests/regressiontests/admin_filters/tests.py455
-rw-r--r--tests/regressiontests/admin_filterspecs/tests.py211
-rw-r--r--tests/regressiontests/admin_views/models.py2
-rw-r--r--tests/regressiontests/modeladmin/tests.py69
6 files changed, 523 insertions, 230 deletions
diff --git a/tests/regressiontests/admin_filterspecs/__init__.py b/tests/regressiontests/admin_filters/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/regressiontests/admin_filterspecs/__init__.py
+++ b/tests/regressiontests/admin_filters/__init__.py
diff --git a/tests/regressiontests/admin_filterspecs/models.py b/tests/regressiontests/admin_filters/models.py
index 5b284c7799..80d54c75a6 100644
--- a/tests/regressiontests/admin_filterspecs/models.py
+++ b/tests/regressiontests/admin_filters/models.py
@@ -2,22 +2,12 @@ from django.db import models
from django.contrib.auth.models import User
class Book(models.Model):
- title = models.CharField(max_length=25)
+ title = models.CharField(max_length=50)
year = models.PositiveIntegerField(null=True, blank=True)
author = models.ForeignKey(User, related_name='books_authored', blank=True, null=True)
contributors = models.ManyToManyField(User, related_name='books_contributed', blank=True, null=True)
+ is_best_seller = models.NullBooleanField(default=0)
+ date_registered = models.DateField(null=True)
def __unicode__(self):
return self.title
-
-class BoolTest(models.Model):
- NO = False
- YES = True
- YES_NO_CHOICES = (
- (NO, 'no'),
- (YES, 'yes')
- )
- completed = models.BooleanField(
- default=NO,
- choices=YES_NO_CHOICES
- )
diff --git a/tests/regressiontests/admin_filters/tests.py b/tests/regressiontests/admin_filters/tests.py
new file mode 100644
index 0000000000..b1bd6ded5f
--- /dev/null
+++ b/tests/regressiontests/admin_filters/tests.py
@@ -0,0 +1,455 @@
+from __future__ import with_statement
+
+import datetime
+
+from django.core.exceptions import ImproperlyConfigured
+from django.test import TestCase, RequestFactory
+from django.utils.encoding import force_unicode
+
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.auth.models import User
+from django.contrib.admin.views.main import ChangeList
+from django.contrib.admin import site, ModelAdmin, SimpleListFilter
+
+from models import Book
+
+def select_by(dictlist, key, value):
+ return [x for x in dictlist if x[key] == value][0]
+
+
+class DecadeListFilter(SimpleListFilter):
+
+ def lookups(self, request):
+ return (
+ ('the 90s', "the 1990's"),
+ ('the 00s', "the 2000's"),
+ ('other', "other decades"),
+ )
+
+ def queryset(self, request, queryset):
+ decade = self.value()
+ if decade == 'the 90s':
+ return queryset.filter(year__gte=1990, year__lte=1999)
+ if decade == 'the 00s':
+ return queryset.filter(year__gte=2000, year__lte=2009)
+
+class DecadeListFilterWithTitleAndParameter(DecadeListFilter):
+ title = 'publication decade'
+ parameter_name = 'publication-decade'
+
+class DecadeListFilterWithoutTitle(DecadeListFilter):
+ parameter_name = 'publication-decade'
+
+class DecadeListFilterWithoutParameter(DecadeListFilter):
+ title = 'publication decade'
+
+class CustomUserAdmin(UserAdmin):
+ list_filter = ('books_authored', 'books_contributed')
+
+class BookAdmin(ModelAdmin):
+ list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered')
+ order_by = '-id'
+
+class DecadeFilterBookAdmin(ModelAdmin):
+ list_filter = ('author', DecadeListFilterWithTitleAndParameter)
+ order_by = '-id'
+
+class DecadeFilterBookAdminWithoutTitle(ModelAdmin):
+ list_filter = (DecadeListFilterWithoutTitle,)
+
+class DecadeFilterBookAdminWithoutParameter(ModelAdmin):
+ list_filter = (DecadeListFilterWithoutParameter,)
+
+class ListFiltersTests(TestCase):
+
+ def setUp(self):
+ self.today = datetime.date.today()
+ self.one_week_ago = self.today - datetime.timedelta(days=7)
+
+ self.request_factory = RequestFactory()
+
+ # Users
+ self.alfred = User.objects.create_user('alfred', 'alfred@example.com')
+ self.bob = User.objects.create_user('bob', 'bob@example.com')
+ self.lisa = User.objects.create_user('lisa', 'lisa@example.com')
+
+ # Books
+ self.djangonaut_book = Book.objects.create(title='Djangonaut: an art of living', year=2009, author=self.alfred, is_best_seller=True, date_registered=self.today)
+ self.bio_book = Book.objects.create(title='Django: a biography', year=1999, author=self.alfred, is_best_seller=False)
+ self.django_book = Book.objects.create(title='The Django Book', year=None, author=self.bob, is_best_seller=None, date_registered=self.today)
+ self.gipsy_book = Book.objects.create(title='Gipsy guitar for dummies', year=2002, is_best_seller=True, date_registered=self.one_week_ago)
+ self.gipsy_book.contributors = [self.bob, self.lisa]
+ self.gipsy_book.save()
+
+ def get_changelist(self, request, model, modeladmin):
+ return ChangeList(request, model, modeladmin.list_display, modeladmin.list_display_links,
+ modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
+ modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
+
+ def test_datefieldlistfilter(self):
+ modeladmin = BookAdmin(Book, site)
+
+ request = self.request_factory.get('/')
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ request = self.request_factory.get('/', {'date_registered__year': self.today.year,
+ 'date_registered__month': self.today.month,
+ 'date_registered__day': self.today.day})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.django_book, self.djangonaut_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][4]
+ self.assertEqual(force_unicode(filterspec.title), u'date_registered')
+ choice = select_by(filterspec.choices(changelist), "display", "Today")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?date_registered__day=%s'
+ '&date_registered__month=%s'
+ '&date_registered__year=%s'
+ % (self.today.day, self.today.month, self.today.year))
+
+ request = self.request_factory.get('/', {'date_registered__year': self.today.year,
+ 'date_registered__month': self.today.month})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ if (self.today.year, self.today.month) == (self.one_week_ago.year, self.one_week_ago.month):
+ # In case one week ago is in the same month.
+ self.assertEqual(list(queryset), [self.gipsy_book, self.django_book, self.djangonaut_book])
+ else:
+ self.assertEqual(list(queryset), [self.django_book, self.djangonaut_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][4]
+ self.assertEqual(force_unicode(filterspec.title), u'date_registered')
+ choice = select_by(filterspec.choices(changelist), "display", "This month")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?date_registered__month=%s'
+ '&date_registered__year=%s'
+ % (self.today.month, self.today.year))
+
+ request = self.request_factory.get('/', {'date_registered__year': self.today.year})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ if self.today.year == self.one_week_ago.year:
+ # In case one week ago is in the same year.
+ self.assertEqual(list(queryset), [self.gipsy_book, self.django_book, self.djangonaut_book])
+ else:
+ self.assertEqual(list(queryset), [self.django_book, self.djangonaut_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][4]
+ self.assertEqual(force_unicode(filterspec.title), u'date_registered')
+ choice = select_by(filterspec.choices(changelist), "display", "This year")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?date_registered__year=%s'
+ % (self.today.year))
+
+ request = self.request_factory.get('/', {'date_registered__gte': self.one_week_ago.strftime('%Y-%m-%d'),
+ 'date_registered__lte': self.today.strftime('%Y-%m-%d')})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.gipsy_book, self.django_book, self.djangonaut_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][4]
+ self.assertEqual(force_unicode(filterspec.title), u'date_registered')
+ choice = select_by(filterspec.choices(changelist), "display", "Past 7 days")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
+ '&date_registered__lte=%s'
+ % (self.one_week_ago.strftime('%Y-%m-%d'), self.today.strftime('%Y-%m-%d')))
+
+ def test_allvaluesfieldlistfilter(self):
+ modeladmin = BookAdmin(Book, site)
+
+ request = self.request_factory.get('/', {'year__isnull': 'True'})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.django_book])
+
+ # Make sure the last choice is None and is selected
+ filterspec = changelist.get_filters(request)[0][0]
+ self.assertEqual(force_unicode(filterspec.title), u'year')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[-1]['selected'], True)
+ self.assertEqual(choices[-1]['query_string'], '?year__isnull=True')
+
+ request = self.request_factory.get('/', {'year': '2002'})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][0]
+ self.assertEqual(force_unicode(filterspec.title), u'year')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[2]['selected'], True)
+ self.assertEqual(choices[2]['query_string'], '?year=2002')
+
+ def test_relatedfieldlistfilter_foreignkey(self):
+ modeladmin = BookAdmin(Book, site)
+
+ request = self.request_factory.get('/', {'author__isnull': 'True'})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.gipsy_book])
+
+ # Make sure the last choice is None and is selected
+ filterspec = changelist.get_filters(request)[0][1]
+ self.assertEqual(force_unicode(filterspec.title), u'author')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[-1]['selected'], True)
+ self.assertEqual(choices[-1]['query_string'], '?author__isnull=True')
+
+ request = self.request_factory.get('/', {'author__id__exact': self.alfred.pk})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][1]
+ self.assertEqual(force_unicode(filterspec.title), u'author')
+ # order of choices depends on User model, which has no order
+ choice = select_by(filterspec.choices(changelist), "display", "alfred")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?author__id__exact=%d' % self.alfred.pk)
+
+ def test_relatedfieldlistfilter_manytomany(self):
+ modeladmin = BookAdmin(Book, site)
+
+ request = self.request_factory.get('/', {'contributors__isnull': 'True'})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.django_book, self.bio_book, self.djangonaut_book])
+
+ # Make sure the last choice is None and is selected
+ filterspec = changelist.get_filters(request)[0][2]
+ self.assertEqual(force_unicode(filterspec.title), u'user')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[-1]['selected'], True)
+ self.assertEqual(choices[-1]['query_string'], '?contributors__isnull=True')
+
+ request = self.request_factory.get('/', {'contributors__id__exact': self.bob.pk})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][2]
+ self.assertEqual(force_unicode(filterspec.title), u'user')
+ choice = select_by(filterspec.choices(changelist), "display", "bob")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?contributors__id__exact=%d' % self.bob.pk)
+
+ def test_relatedfieldlistfilter_reverse_relationships(self):
+ modeladmin = CustomUserAdmin(User, site)
+
+ # FK relationship -----
+ request = self.request_factory.get('/', {'books_authored__isnull': 'True'})
+ changelist = self.get_changelist(request, User, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.lisa])
+
+ # Make sure the last choice is None and is selected
+ filterspec = changelist.get_filters(request)[0][0]
+ self.assertEqual(force_unicode(filterspec.title), u'book')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[-1]['selected'], True)
+ self.assertEqual(choices[-1]['query_string'], '?books_authored__isnull=True')
+
+ request = self.request_factory.get('/', {'books_authored__id__exact': self.bio_book.pk})
+ changelist = self.get_changelist(request, User, modeladmin)
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][0]
+ self.assertEqual(force_unicode(filterspec.title), u'book')
+ choice = select_by(filterspec.choices(changelist), "display", self.bio_book.title)
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?books_authored__id__exact=%d' % self.bio_book.pk)
+
+ # M2M relationship -----
+ request = self.request_factory.get('/', {'books_contributed__isnull': 'True'})
+ changelist = self.get_changelist(request, User, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.alfred])
+
+ # Make sure the last choice is None and is selected
+ filterspec = changelist.get_filters(request)[0][1]
+ self.assertEqual(force_unicode(filterspec.title), u'book')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[-1]['selected'], True)
+ self.assertEqual(choices[-1]['query_string'], '?books_contributed__isnull=True')
+
+ request = self.request_factory.get('/', {'books_contributed__id__exact': self.django_book.pk})
+ changelist = self.get_changelist(request, User, modeladmin)
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][1]
+ self.assertEqual(force_unicode(filterspec.title), u'book')
+ choice = select_by(filterspec.choices(changelist), "display", self.django_book.title)
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?books_contributed__id__exact=%d' % self.django_book.pk)
+
+ def test_booleanfieldlistfilter(self):
+ modeladmin = BookAdmin(Book, site)
+ self.verify_booleanfieldlistfilter(modeladmin)
+
+ def test_booleanfieldlistfilter_tuple(self):
+ modeladmin = BookAdmin(Book, site)
+ self.verify_booleanfieldlistfilter(modeladmin)
+
+ def verify_booleanfieldlistfilter(self, modeladmin):
+ request = self.request_factory.get('/')
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ request = self.request_factory.get('/', {'is_best_seller__exact': 0})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.bio_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][3]
+ self.assertEqual(force_unicode(filterspec.title), u'is_best_seller')
+ choice = select_by(filterspec.choices(changelist), "display", "No")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?is_best_seller__exact=0')
+
+ request = self.request_factory.get('/', {'is_best_seller__exact': 1})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.gipsy_book, self.djangonaut_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][3]
+ self.assertEqual(force_unicode(filterspec.title), u'is_best_seller')
+ choice = select_by(filterspec.choices(changelist), "display", "Yes")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?is_best_seller__exact=1')
+
+ request = self.request_factory.get('/', {'is_best_seller__isnull': 'True'})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.django_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][3]
+ self.assertEqual(force_unicode(filterspec.title), u'is_best_seller')
+ choice = select_by(filterspec.choices(changelist), "display", "Unknown")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?is_best_seller__isnull=True')
+
+ def test_simplelistfilter(self):
+ modeladmin = DecadeFilterBookAdmin(Book, site)
+
+ # Make sure that the first option is 'All' ---------------------------
+
+ request = self.request_factory.get('/', {})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), list(Book.objects.all().order_by('-id')))
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][1]
+ self.assertEqual(force_unicode(filterspec.title), u'publication decade')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[0]['display'], u'All')
+ self.assertEqual(choices[0]['selected'], True)
+ self.assertEqual(choices[0]['query_string'], '?')
+
+ # Look for books in the 1990s ----------------------------------------
+
+ request = self.request_factory.get('/', {'publication-decade': 'the 90s'})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.bio_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][1]
+ self.assertEqual(force_unicode(filterspec.title), u'publication decade')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[1]['display'], u'the 1990\'s')
+ self.assertEqual(choices[1]['selected'], True)
+ self.assertEqual(choices[1]['query_string'], '?publication-decade=the+90s')
+
+ # Look for books in the 2000s ----------------------------------------
+
+ request = self.request_factory.get('/', {'publication-decade': 'the 00s'})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.gipsy_book, self.djangonaut_book])
+
+ # Make sure the correct choice is selected
+ filterspec = changelist.get_filters(request)[0][1]
+ self.assertEqual(force_unicode(filterspec.title), u'publication decade')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[2]['display'], u'the 2000\'s')
+ self.assertEqual(choices[2]['selected'], True)
+ self.assertEqual(choices[2]['query_string'], '?publication-decade=the+00s')
+
+ # Combine multiple filters -------------------------------------------
+
+ request = self.request_factory.get('/', {'publication-decade': 'the 00s', 'author__id__exact': self.alfred.pk})
+ changelist = self.get_changelist(request, Book, modeladmin)
+
+ # Make sure the correct queryset is returned
+ queryset = changelist.get_query_set(request)
+ self.assertEqual(list(queryset), [self.djangonaut_book])
+
+ # Make sure the correct choices are selected
+ filterspec = changelist.get_filters(request)[0][1]
+ self.assertEqual(force_unicode(filterspec.title), u'publication decade')
+ choices = list(filterspec.choices(changelist))
+ self.assertEqual(choices[2]['display'], u'the 2000\'s')
+ self.assertEqual(choices[2]['selected'], True)
+ self.assertEqual(choices[2]['query_string'], '?publication-decade=the+00s&author__id__exact=%s' % self.alfred.pk)
+
+ filterspec = changelist.get_filters(request)[0][0]
+ self.assertEqual(force_unicode(filterspec.title), u'author')
+ choice = select_by(filterspec.choices(changelist), "display", "alfred")
+ self.assertEqual(choice['selected'], True)
+ self.assertEqual(choice['query_string'], '?publication-decade=the+00s&author__id__exact=%s' % self.alfred.pk)
+
+ def test_listfilter_without_title(self):
+ """
+ Any filter must define a title.
+ """
+ modeladmin = DecadeFilterBookAdminWithoutTitle(Book, site)
+ request = self.request_factory.get('/', {})
+ self.assertRaisesRegexp(ImproperlyConfigured,
+ "The list filter 'DecadeListFilterWithoutTitle' does not specify a 'title'.",
+ self.get_changelist, request, Book, modeladmin)
+
+ def test_simplelistfilter_without_parameter(self):
+ """
+ Any SimpleListFilter must define a parameter_name.
+ """
+ modeladmin = DecadeFilterBookAdminWithoutParameter(Book, site)
+ request = self.request_factory.get('/', {})
+ self.assertRaisesRegexp(ImproperlyConfigured,
+ "The list filter 'DecadeListFilterWithoutParameter' does not specify a 'parameter_name'.",
+ self.get_changelist, request, Book, modeladmin)
diff --git a/tests/regressiontests/admin_filterspecs/tests.py b/tests/regressiontests/admin_filterspecs/tests.py
deleted file mode 100644
index 8b9e734313..0000000000
--- a/tests/regressiontests/admin_filterspecs/tests.py
+++ /dev/null
@@ -1,211 +0,0 @@
-from django.contrib.auth.admin import UserAdmin
-from django.test import TestCase
-from django.test.client import RequestFactory
-from django.contrib.auth.models import User
-from django.contrib import admin
-from django.contrib.admin.views.main import ChangeList
-from django.utils.encoding import force_unicode
-
-from models import Book, BoolTest
-
-def select_by(dictlist, key, value):
- return [x for x in dictlist if x[key] == value][0]
-
-class FilterSpecsTests(TestCase):
-
- def setUp(self):
- # Users
- self.alfred = User.objects.create_user('alfred', 'alfred@example.com')
- self.bob = User.objects.create_user('bob', 'bob@example.com')
- lisa = User.objects.create_user('lisa', 'lisa@example.com')
-
- #Books
- self.bio_book = Book.objects.create(title='Django: a biography', year=1999, author=self.alfred)
- self.django_book = Book.objects.create(title='The Django Book', year=None, author=self.bob)
- gipsy_book = Book.objects.create(title='Gipsy guitar for dummies', year=2002)
- gipsy_book.contributors = [self.bob, lisa]
- gipsy_book.save()
-
- # BoolTests
- self.trueTest = BoolTest.objects.create(completed=True)
- self.falseTest = BoolTest.objects.create(completed=False)
-
- self.request_factory = RequestFactory()
-
-
- def get_changelist(self, request, model, modeladmin):
- return ChangeList(request, model, modeladmin.list_display, modeladmin.list_display_links,
- modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
- modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
-
- def test_AllValuesFilterSpec(self):
- modeladmin = BookAdmin(Book, admin.site)
-
- request = self.request_factory.get('/', {'year__isnull': 'True'})
- changelist = self.get_changelist(request, Book, modeladmin)
-
- # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
- queryset = changelist.get_query_set()
-
- # Make sure the last choice is None and is selected
- filterspec = changelist.get_filters(request)[0][0]
- self.assertEqual(force_unicode(filterspec.title()), u'year')
- choices = list(filterspec.choices(changelist))
- self.assertEqual(choices[-1]['selected'], True)
- self.assertEqual(choices[-1]['query_string'], '?year__isnull=True')
-
- request = self.request_factory.get('/', {'year': '2002'})
- changelist = self.get_changelist(request, Book, modeladmin)
-
- # Make sure the correct choice is selected
- filterspec = changelist.get_filters(request)[0][0]
- self.assertEqual(force_unicode(filterspec.title()), u'year')
- choices = list(filterspec.choices(changelist))
- self.assertEqual(choices[2]['selected'], True)
- self.assertEqual(choices[2]['query_string'], '?year=2002')
-
- def test_RelatedFilterSpec_ForeignKey(self):
- modeladmin = BookAdmin(Book, admin.site)
-
- request = self.request_factory.get('/', {'author__isnull': 'True'})
- changelist = ChangeList(request, Book, modeladmin.list_display, modeladmin.list_display_links,
- modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
- modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
-
- # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
- queryset = changelist.get_query_set()
-
- # Make sure the last choice is None and is selected
- filterspec = changelist.get_filters(request)[0][1]
- self.assertEqual(force_unicode(filterspec.title()), u'author')
- choices = list(filterspec.choices(changelist))
- self.assertEqual(choices[-1]['selected'], True)
- self.assertEqual(choices[-1]['query_string'], '?author__isnull=True')
-
- request = self.request_factory.get('/', {'author__id__exact': self.alfred.pk})
- changelist = self.get_changelist(request, Book, modeladmin)
-
- # Make sure the correct choice is selected
- filterspec = changelist.get_filters(request)[0][1]
- self.assertEqual(force_unicode(filterspec.title()), u'author')
- # order of choices depends on User model, which has no order
- choice = select_by(filterspec.choices(changelist), "display", "alfred")
- self.assertEqual(choice['selected'], True)
- self.assertEqual(choice['query_string'], '?author__id__exact=%d' % self.alfred.pk)
-
- def test_RelatedFilterSpec_ManyToMany(self):
- modeladmin = BookAdmin(Book, admin.site)
-
- request = self.request_factory.get('/', {'contributors__isnull': 'True'})
- changelist = self.get_changelist(request, Book, modeladmin)
-
- # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
- queryset = changelist.get_query_set()
-
- # Make sure the last choice is None and is selected
- filterspec = changelist.get_filters(request)[0][2]
- self.assertEqual(force_unicode(filterspec.title()), u'user')
- choices = list(filterspec.choices(changelist))
- self.assertEqual(choices[-1]['selected'], True)
- self.assertEqual(choices[-1]['query_string'], '?contributors__isnull=True')
-
- request = self.request_factory.get('/', {'contributors__id__exact': self.bob.pk})
- changelist = self.get_changelist(request, Book, modeladmin)
-
- # Make sure the correct choice is selected
- filterspec = changelist.get_filters(request)[0][2]
- self.assertEqual(force_unicode(filterspec.title()), u'user')
- choice = select_by(filterspec.choices(changelist), "display", "bob")
- self.assertEqual(choice['selected'], True)
- self.assertEqual(choice['query_string'], '?contributors__id__exact=%d' % self.bob.pk)
-
-
- def test_RelatedFilterSpec_reverse_relationships(self):
- modeladmin = CustomUserAdmin(User, admin.site)
-
- # FK relationship -----
- request = self.request_factory.get('/', {'books_authored__isnull': 'True'})
- changelist = self.get_changelist(request, User, modeladmin)
-
- # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
- queryset = changelist.get_query_set()
-
- # Make sure the last choice is None and is selected
- filterspec = changelist.get_filters(request)[0][0]
- self.assertEqual(force_unicode(filterspec.title()), u'book')
- choices = list(filterspec.choices(changelist))
- self.assertEqual(choices[-1]['selected'], True)
- self.assertEqual(choices[-1]['query_string'], '?books_authored__isnull=True')
-
- request = self.request_factory.get('/', {'books_authored__id__exact': self.bio_book.pk})
- changelist = self.get_changelist(request, User, modeladmin)
-
- # Make sure the correct choice is selected
- filterspec = changelist.get_filters(request)[0][0]
- self.assertEqual(force_unicode(filterspec.title()), u'book')
- choice = select_by(filterspec.choices(changelist), "display", self.bio_book.title)
- self.assertEqual(choice['selected'], True)
- self.assertEqual(choice['query_string'], '?books_authored__id__exact=%d' % self.bio_book.pk)
-
- # M2M relationship -----
- request = self.request_factory.get('/', {'books_contributed__isnull': 'True'})
- changelist = self.get_changelist(request, User, modeladmin)
-
- # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
- queryset = changelist.get_query_set()
-
- # Make sure the last choice is None and is selected
- filterspec = changelist.get_filters(request)[0][1]
- self.assertEqual(force_unicode(filterspec.title()), u'book')
- choices = list(filterspec.choices(changelist))
- self.assertEqual(choices[-1]['selected'], True)
- self.assertEqual(choices[-1]['query_string'], '?books_contributed__isnull=True')
-
- request = self.request_factory.get('/', {'books_contributed__id__exact': self.django_book.pk})
- changelist = self.get_changelist(request, User, modeladmin)
-
- # Make sure the correct choice is selected
- filterspec = changelist.get_filters(request)[0][1]
- self.assertEqual(force_unicode(filterspec.title()), u'book')
- choice = select_by(filterspec.choices(changelist), "display", self.django_book.title)
- self.assertEqual(choice['selected'], True)
- self.assertEqual(choice['query_string'], '?books_contributed__id__exact=%d' % self.django_book.pk)
-
- def test_BooleanFilterSpec(self):
- modeladmin = BoolTestAdmin(BoolTest, admin.site)
-
- request = self.request_factory.get('/')
- changelist = ChangeList(request, BoolTest, modeladmin.list_display, modeladmin.list_display_links,
- modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
- modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
-
- # Make sure changelist.get_query_set() does not raise IncorrectLookupParameters
- queryset = changelist.get_query_set()
-
- # Make sure the last choice is None and is selected
- filterspec = changelist.get_filters(request)[0][0]
- self.assertEqual(force_unicode(filterspec.title()), u'completed')
- choices = list(filterspec.choices(changelist))
- self.assertEqual(choices[-1]['selected'], False)
- self.assertEqual(choices[-1]['query_string'], '?completed__exact=0')
-
- request = self.request_factory.get('/', {'completed__exact': 1})
- changelist = self.get_changelist(request, BoolTest, modeladmin)
-
- # Make sure the correct choice is selected
- filterspec = changelist.get_filters(request)[0][0]
- self.assertEqual(force_unicode(filterspec.title()), u'completed')
- # order of choices depends on User model, which has no order
- choice = select_by(filterspec.choices(changelist), "display", "Yes")
- self.assertEqual(choice['selected'], True)
- self.assertEqual(choice['query_string'], '?completed__exact=1')
-
-class CustomUserAdmin(UserAdmin):
- list_filter = ('books_authored', 'books_contributed')
-
-class BookAdmin(admin.ModelAdmin):
- list_filter = ('year', 'author', 'contributors')
- order_by = '-id'
-
-class BoolTestAdmin(admin.ModelAdmin):
- list_filter = ('completed',)
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
index 97f6708e40..6e34ee1272 100644
--- a/tests/regressiontests/admin_views/models.py
+++ b/tests/regressiontests/admin_views/models.py
@@ -611,7 +611,7 @@ class Gadget(models.Model):
return self.name
class CustomChangeList(ChangeList):
- def get_query_set(self):
+ def get_query_set(self, request):
return self.root_query_set.filter(pk=9999) # Does not exist
class GadgetAdmin(admin.ModelAdmin):
diff --git a/tests/regressiontests/modeladmin/tests.py b/tests/regressiontests/modeladmin/tests.py
index a20e579026..530b476b7c 100644
--- a/tests/regressiontests/modeladmin/tests.py
+++ b/tests/regressiontests/modeladmin/tests.py
@@ -2,19 +2,21 @@ from datetime import date
from django import forms
from django.conf import settings
-from django.contrib.admin.options import ModelAdmin, TabularInline, \
- HORIZONTAL, VERTICAL
+from django.contrib.admin.options import (ModelAdmin, TabularInline,
+ HORIZONTAL, VERTICAL)
from django.contrib.admin.sites import AdminSite
from django.contrib.admin.validation import validate
from django.contrib.admin.widgets import AdminDateWidget, AdminRadioSelect
+from django.contrib.admin import (SimpleListFilter,
+ BooleanFieldListFilter)
from django.core.exceptions import ImproperlyConfigured
from django.forms.models import BaseModelFormSet
from django.forms.widgets import Select
from django.test import TestCase
from django.utils import unittest
-from models import Band, Concert, ValidationTestModel, \
- ValidationTestInlineModel
+from models import (Band, Concert, ValidationTestModel,
+ ValidationTestInlineModel)
# None of the following tests really depend on the content of the request,
@@ -851,8 +853,65 @@ class ValidationTests(unittest.TestCase):
ValidationTestModel,
)
+ class RandomClass(object):
+ pass
+
+ class ValidationTestModelAdmin(ModelAdmin):
+ list_filter = (RandomClass,)
+
+ self.assertRaisesRegexp(
+ ImproperlyConfigured,
+ "'ValidationTestModelAdmin.list_filter\[0\]' is 'RandomClass' which is not a descendant of ListFilter.",
+ validate,
+ ValidationTestModelAdmin,
+ ValidationTestModel,
+ )
+
+ class ValidationTestModelAdmin(ModelAdmin):
+ list_filter = (('is_active', RandomClass),)
+
+ self.assertRaisesRegexp(
+ ImproperlyConfigured,
+ "'ValidationTestModelAdmin.list_filter\[0\]\[1\]' is 'RandomClass' which is not of type FieldListFilter.",
+ validate,
+ ValidationTestModelAdmin,
+ ValidationTestModel,
+ )
+
+ class AwesomeFilter(SimpleListFilter):
+ def get_title(self):
+ return 'awesomeness'
+ def get_choices(self, request):
+ return (('bit', 'A bit awesome'), ('very', 'Very awesome'), )
+ def get_query_set(self, cl, qs):
+ return qs
+
+ class ValidationTestModelAdmin(ModelAdmin):
+ list_filter = (('is_active', AwesomeFilter),)
+
+ self.assertRaisesRegexp(
+ ImproperlyConfigured,
+ "'ValidationTestModelAdmin.list_filter\[0\]\[1\]' is 'AwesomeFilter' which is not of type FieldListFilter.",
+ validate,
+ ValidationTestModelAdmin,
+ ValidationTestModel,
+ )
+
+ class ValidationTestModelAdmin(ModelAdmin):
+ list_filter = (BooleanFieldListFilter,)
+
+ self.assertRaisesRegexp(
+ ImproperlyConfigured,
+ "'ValidationTestModelAdmin.list_filter\[0\]' is 'BooleanFieldListFilter' which is of type FieldListFilter but is not associated with a field name.",
+ validate,
+ ValidationTestModelAdmin,
+ ValidationTestModel,
+ )
+
+ # Valid declarations below -----------
+
class ValidationTestModelAdmin(ModelAdmin):
- list_filter = ('is_active',)
+ list_filter = ('is_active', AwesomeFilter, ('is_active', BooleanFieldListFilter))
validate(ValidationTestModelAdmin, ValidationTestModel)