Fixed #26277 -- Added support for null values in ChoicesFieldListFilter.
This commit is contained in:
parent
929684d6ee
commit
069319396f
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue