Fixed #26277 -- Added support for null values in ChoicesFieldListFilter.

This commit is contained in:
Vincenzo Pandolfo 2016-03-30 16:05:31 +01:00 committed by Tim Graham
parent 929684d6ee
commit 069319396f
3 changed files with 44 additions and 3 deletions

View File

@ -269,25 +269,43 @@ FieldListFilter.register(
class ChoicesFieldListFilter(FieldListFilter):
def __init__(self, field, request, params, model, model_admin, field_path):
self.lookup_kwarg = '%s__exact' % field_path
self.lookup_kwarg_isnull = '%s__isnull' % field_path
self.lookup_val = request.GET.get(self.lookup_kwarg)
self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull)
super(ChoicesFieldListFilter, self).__init__(
field, request, params, model, model_admin, field_path)
def expected_parameters(self):
return [self.lookup_kwarg]
return [self.lookup_kwarg, self.lookup_kwarg_isnull]
def choices(self, changelist):
yield {
'selected': self.lookup_val is None,
'query_string': changelist.get_query_string({}, [self.lookup_kwarg]),
'query_string': changelist.get_query_string(
{}, [self.lookup_kwarg, self.lookup_kwarg_isnull]
),
'display': _('All')
}
none_title = ''
for lookup, title in self.field.flatchoices:
if lookup is None:
none_title = title
continue
yield {
'selected': smart_text(lookup) == self.lookup_val,
'query_string': changelist.get_query_string({self.lookup_kwarg: lookup}),
'query_string': changelist.get_query_string(
{self.lookup_kwarg: lookup}, [self.lookup_kwarg_isnull]
),
'display': title,
}
if none_title:
yield {
'selected': bool(self.lookup_val_isnull),
'query_string': changelist.get_query_string({
self.lookup_kwarg_isnull: 'True',
}, [self.lookup_kwarg]),
'display': none_title,
}
FieldListFilter.register(lambda f: bool(f.choices), ChoicesFieldListFilter)

View File

@ -75,5 +75,12 @@ class Bookmark(models.Model):
url = models.URLField()
tags = GenericRelation(TaggedItem)
CHOICES = [
('a', 'A'),
(None, 'None'),
('', '-'),
]
none_or_null = models.CharField(max_length=20, choices=CHOICES, blank=True, null=True)
def __str__(self):
return self.url

View File

@ -302,6 +302,22 @@ class ListFiltersTests(TestCase):
modeladmin.list_max_show_all, modeladmin.list_editable, modeladmin,
)
def test_choicesfieldlistfilter_has_none_choice(self):
"""
The last choice is for the None value.
"""
class BookmarkChoicesAdmin(ModelAdmin):
list_display = ['none_or_null']
list_filter = ['none_or_null']
modeladmin = BookmarkChoicesAdmin(Bookmark, site)
request = self.request_factory.get('/', {})
changelist = self.get_changelist(request, Bookmark, modeladmin)
filterspec = changelist.get_filters(request)[0][0]
choices = list(filterspec.choices(changelist))
self.assertEqual(choices[-1]['display'], 'None')
self.assertEqual(choices[-1]['query_string'], '?none_or_null__isnull=True')
def test_datefieldlistfilter(self):
modeladmin = BookAdmin(Book, site)