Fixed #31636 -- Made BooleanFieldListFilter respect Field.choices.
This commit is contained in:
parent
fed257ddff
commit
580a4341cb
|
@ -244,10 +244,12 @@ class BooleanFieldListFilter(FieldListFilter):
|
||||||
return [self.lookup_kwarg, self.lookup_kwarg2]
|
return [self.lookup_kwarg, self.lookup_kwarg2]
|
||||||
|
|
||||||
def choices(self, changelist):
|
def choices(self, changelist):
|
||||||
|
field_choices = dict(self.field.flatchoices)
|
||||||
for lookup, title in (
|
for lookup, title in (
|
||||||
(None, _('All')),
|
(None, _('All')),
|
||||||
('1', _('Yes')),
|
('1', field_choices.get(True, _('Yes'))),
|
||||||
('0', _('No'))):
|
('0', field_choices.get(False, _('No'))),
|
||||||
|
):
|
||||||
yield {
|
yield {
|
||||||
'selected': self.lookup_val == lookup and not self.lookup_val2,
|
'selected': self.lookup_val == lookup and not self.lookup_val2,
|
||||||
'query_string': changelist.get_query_string({self.lookup_kwarg: lookup}, [self.lookup_kwarg2]),
|
'query_string': changelist.get_query_string({self.lookup_kwarg: lookup}, [self.lookup_kwarg2]),
|
||||||
|
@ -257,7 +259,7 @@ class BooleanFieldListFilter(FieldListFilter):
|
||||||
yield {
|
yield {
|
||||||
'selected': self.lookup_val2 == 'True',
|
'selected': self.lookup_val2 == 'True',
|
||||||
'query_string': changelist.get_query_string({self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]),
|
'query_string': changelist.get_query_string({self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]),
|
||||||
'display': _('Unknown'),
|
'display': field_choices.get(None, _('Unknown')),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,11 @@ class Book(models.Model):
|
||||||
is_best_seller = models.BooleanField(default=0, null=True)
|
is_best_seller = models.BooleanField(default=0, null=True)
|
||||||
is_best_seller2 = models.NullBooleanField(default=0)
|
is_best_seller2 = models.NullBooleanField(default=0)
|
||||||
date_registered = models.DateField(null=True)
|
date_registered = models.DateField(null=True)
|
||||||
|
availability = models.BooleanField(choices=(
|
||||||
|
(False, 'Paid'),
|
||||||
|
(True, 'Free'),
|
||||||
|
(None, 'Obscure'),
|
||||||
|
), null=True)
|
||||||
# This field name is intentionally 2 characters long (#16080).
|
# This field name is intentionally 2 characters long (#16080).
|
||||||
no = models.IntegerField(verbose_name='number', blank=True, null=True)
|
no = models.IntegerField(verbose_name='number', blank=True, null=True)
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ class CustomUserAdmin(UserAdmin):
|
||||||
|
|
||||||
|
|
||||||
class BookAdmin(ModelAdmin):
|
class BookAdmin(ModelAdmin):
|
||||||
list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered', 'no')
|
list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered', 'no', 'availability')
|
||||||
ordering = ('-id',)
|
ordering = ('-id',)
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,6 +156,7 @@ class BookAdminWithTupleBooleanFilter(BookAdmin):
|
||||||
('is_best_seller', BooleanFieldListFilter),
|
('is_best_seller', BooleanFieldListFilter),
|
||||||
'date_registered',
|
'date_registered',
|
||||||
'no',
|
'no',
|
||||||
|
('availability', BooleanFieldListFilter),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -288,22 +289,22 @@ class ListFiltersTests(TestCase):
|
||||||
cls.djangonaut_book = Book.objects.create(
|
cls.djangonaut_book = Book.objects.create(
|
||||||
title='Djangonaut: an art of living', year=2009,
|
title='Djangonaut: an art of living', year=2009,
|
||||||
author=cls.alfred, is_best_seller=True, date_registered=cls.today,
|
author=cls.alfred, is_best_seller=True, date_registered=cls.today,
|
||||||
is_best_seller2=True,
|
is_best_seller2=True, availability=True,
|
||||||
)
|
)
|
||||||
cls.bio_book = Book.objects.create(
|
cls.bio_book = Book.objects.create(
|
||||||
title='Django: a biography', year=1999, author=cls.alfred,
|
title='Django: a biography', year=1999, author=cls.alfred,
|
||||||
is_best_seller=False, no=207,
|
is_best_seller=False, no=207,
|
||||||
is_best_seller2=False,
|
is_best_seller2=False, availability=False,
|
||||||
)
|
)
|
||||||
cls.django_book = Book.objects.create(
|
cls.django_book = Book.objects.create(
|
||||||
title='The Django Book', year=None, author=cls.bob,
|
title='The Django Book', year=None, author=cls.bob,
|
||||||
is_best_seller=None, date_registered=cls.today, no=103,
|
is_best_seller=None, date_registered=cls.today, no=103,
|
||||||
is_best_seller2=None,
|
is_best_seller2=None, availability=True,
|
||||||
)
|
)
|
||||||
cls.guitar_book = Book.objects.create(
|
cls.guitar_book = Book.objects.create(
|
||||||
title='Guitar for dummies', year=2002, is_best_seller=True,
|
title='Guitar for dummies', year=2002, is_best_seller=True,
|
||||||
date_registered=cls.one_week_ago,
|
date_registered=cls.one_week_ago,
|
||||||
is_best_seller2=True,
|
is_best_seller2=True, availability=None,
|
||||||
)
|
)
|
||||||
cls.guitar_book.contributors.set([cls.bob, cls.lisa])
|
cls.guitar_book.contributors.set([cls.bob, cls.lisa])
|
||||||
|
|
||||||
|
@ -956,6 +957,63 @@ class ListFiltersTests(TestCase):
|
||||||
self.assertIs(choice['selected'], True)
|
self.assertIs(choice['selected'], True)
|
||||||
self.assertEqual(choice['query_string'], '?is_best_seller__isnull=True')
|
self.assertEqual(choice['query_string'], '?is_best_seller__isnull=True')
|
||||||
|
|
||||||
|
def test_booleanfieldlistfilter_choices(self):
|
||||||
|
modeladmin = BookAdmin(Book, site)
|
||||||
|
self.verify_booleanfieldlistfilter_choices(modeladmin)
|
||||||
|
|
||||||
|
def test_booleanfieldlistfilter_tuple_choices(self):
|
||||||
|
modeladmin = BookAdminWithTupleBooleanFilter(Book, site)
|
||||||
|
self.verify_booleanfieldlistfilter_choices(modeladmin)
|
||||||
|
|
||||||
|
def verify_booleanfieldlistfilter_choices(self, modeladmin):
|
||||||
|
# False.
|
||||||
|
request = self.request_factory.get('/', {'availability__exact': 0})
|
||||||
|
request.user = self.alfred
|
||||||
|
changelist = modeladmin.get_changelist_instance(request)
|
||||||
|
queryset = changelist.get_queryset(request)
|
||||||
|
self.assertEqual(list(queryset), [self.bio_book])
|
||||||
|
filterspec = changelist.get_filters(request)[0][6]
|
||||||
|
self.assertEqual(filterspec.title, 'availability')
|
||||||
|
choice = select_by(filterspec.choices(changelist), 'display', 'Paid')
|
||||||
|
self.assertIs(choice['selected'], True)
|
||||||
|
self.assertEqual(choice['query_string'], '?availability__exact=0')
|
||||||
|
# True.
|
||||||
|
request = self.request_factory.get('/', {'availability__exact': 1})
|
||||||
|
request.user = self.alfred
|
||||||
|
changelist = modeladmin.get_changelist_instance(request)
|
||||||
|
queryset = changelist.get_queryset(request)
|
||||||
|
self.assertEqual(list(queryset), [self.django_book, self.djangonaut_book])
|
||||||
|
filterspec = changelist.get_filters(request)[0][6]
|
||||||
|
self.assertEqual(filterspec.title, 'availability')
|
||||||
|
choice = select_by(filterspec.choices(changelist), 'display', 'Free')
|
||||||
|
self.assertIs(choice['selected'], True)
|
||||||
|
self.assertEqual(choice['query_string'], '?availability__exact=1')
|
||||||
|
# None.
|
||||||
|
request = self.request_factory.get('/', {'availability__isnull': 'True'})
|
||||||
|
request.user = self.alfred
|
||||||
|
changelist = modeladmin.get_changelist_instance(request)
|
||||||
|
queryset = changelist.get_queryset(request)
|
||||||
|
self.assertEqual(list(queryset), [self.guitar_book])
|
||||||
|
filterspec = changelist.get_filters(request)[0][6]
|
||||||
|
self.assertEqual(filterspec.title, 'availability')
|
||||||
|
choice = select_by(filterspec.choices(changelist), 'display', 'Obscure')
|
||||||
|
self.assertIs(choice['selected'], True)
|
||||||
|
self.assertEqual(choice['query_string'], '?availability__isnull=True')
|
||||||
|
# All.
|
||||||
|
request = self.request_factory.get('/')
|
||||||
|
request.user = self.alfred
|
||||||
|
changelist = modeladmin.get_changelist_instance(request)
|
||||||
|
queryset = changelist.get_queryset(request)
|
||||||
|
self.assertEqual(
|
||||||
|
list(queryset),
|
||||||
|
[self.guitar_book, self.django_book, self.bio_book, self.djangonaut_book],
|
||||||
|
)
|
||||||
|
filterspec = changelist.get_filters(request)[0][6]
|
||||||
|
self.assertEqual(filterspec.title, 'availability')
|
||||||
|
choice = select_by(filterspec.choices(changelist), 'display', 'All')
|
||||||
|
self.assertIs(choice['selected'], True)
|
||||||
|
self.assertEqual(choice['query_string'], '?')
|
||||||
|
|
||||||
def test_booleanfieldlistfilter_nullbooleanfield(self):
|
def test_booleanfieldlistfilter_nullbooleanfield(self):
|
||||||
modeladmin = BookAdmin2(Book, site)
|
modeladmin = BookAdmin2(Book, site)
|
||||||
|
|
||||||
|
@ -1212,7 +1270,7 @@ class ListFiltersTests(TestCase):
|
||||||
queryset = changelist.get_queryset(request)
|
queryset = changelist.get_queryset(request)
|
||||||
self.assertEqual(list(queryset), [self.bio_book])
|
self.assertEqual(list(queryset), [self.bio_book])
|
||||||
|
|
||||||
filterspec = changelist.get_filters(request)[0][-1]
|
filterspec = changelist.get_filters(request)[0][5]
|
||||||
self.assertEqual(filterspec.title, 'number')
|
self.assertEqual(filterspec.title, 'number')
|
||||||
choices = list(filterspec.choices(changelist))
|
choices = list(filterspec.choices(changelist))
|
||||||
self.assertIs(choices[2]['selected'], True)
|
self.assertIs(choices[2]['selected'], True)
|
||||||
|
|
Loading…
Reference in New Issue