Skip to content

Commit

Permalink
Fixed #26277 -- Added support for null values in ChoicesFieldListFilter.
Browse files Browse the repository at this point in the history
  • Loading branch information
vincepandolfo authored and timgraham committed May 12, 2016
1 parent 929684d commit 0693193
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 3 deletions.
24 changes: 21 additions & 3 deletions django/contrib/admin/filters.py
Expand Up @@ -269,25 +269,43 @@ def choices(self, changelist):
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)

Expand Down
7 changes: 7 additions & 0 deletions tests/admin_filters/models.py
Expand Up @@ -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
16 changes: 16 additions & 0 deletions tests/admin_filters/tests.py
Expand Up @@ -302,6 +302,22 @@ def get_changelist(self, request, model, modeladmin):
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)

Expand Down

0 comments on commit 0693193

Please sign in to comment.