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):
|
class ChoicesFieldListFilter(FieldListFilter):
|
||||||
def __init__(self, field, request, params, model, model_admin, field_path):
|
def __init__(self, field, request, params, model, model_admin, field_path):
|
||||||
self.lookup_kwarg = '%s__exact' % 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 = request.GET.get(self.lookup_kwarg)
|
||||||
|
self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull)
|
||||||
super(ChoicesFieldListFilter, self).__init__(
|
super(ChoicesFieldListFilter, self).__init__(
|
||||||
field, request, params, model, model_admin, field_path)
|
field, request, params, model, model_admin, field_path)
|
||||||
|
|
||||||
def expected_parameters(self):
|
def expected_parameters(self):
|
||||||
return [self.lookup_kwarg]
|
return [self.lookup_kwarg, self.lookup_kwarg_isnull]
|
||||||
|
|
||||||
def choices(self, changelist):
|
def choices(self, changelist):
|
||||||
yield {
|
yield {
|
||||||
'selected': self.lookup_val is None,
|
'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')
|
'display': _('All')
|
||||||
}
|
}
|
||||||
|
none_title = ''
|
||||||
for lookup, title in self.field.flatchoices:
|
for lookup, title in self.field.flatchoices:
|
||||||
|
if lookup is None:
|
||||||
|
none_title = title
|
||||||
|
continue
|
||||||
yield {
|
yield {
|
||||||
'selected': smart_text(lookup) == self.lookup_val,
|
'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,
|
'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)
|
FieldListFilter.register(lambda f: bool(f.choices), ChoicesFieldListFilter)
|
||||||
|
|
||||||
|
|
|
@ -75,5 +75,12 @@ class Bookmark(models.Model):
|
||||||
url = models.URLField()
|
url = models.URLField()
|
||||||
tags = GenericRelation(TaggedItem)
|
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):
|
def __str__(self):
|
||||||
return self.url
|
return self.url
|
||||||
|
|
|
@ -302,6 +302,22 @@ class ListFiltersTests(TestCase):
|
||||||
modeladmin.list_max_show_all, modeladmin.list_editable, 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):
|
def test_datefieldlistfilter(self):
|
||||||
modeladmin = BookAdmin(Book, site)
|
modeladmin = BookAdmin(Book, site)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue