Reputation: 227
by default django admin's list_filter
provide all filters available in model choices. but apart from those I want one more filter, lets say it 'None' filter.
class Mymodel:
char choice field (choices=(('1', 'txt1', '2', 'txt2')), null=True)
class MymodelAdmin(admin.ModelAdmin):
...
list_filter = [..., choice_field, ...]
...
this will set three filter in admin panel(right hand side filters) , All, 'txt1', 'txt2'
. right?
I want one more filter 'None' if no value is assign from choices.
what I tried so far..
class ChoiceFieldFilter(admin.filters.ChoicesFieldListFilter):
def __init__(self, *args, **kwargs):
super(ChoiceFieldFilter, self).__init__(*args, **kwargs)
self.lookup_val = [('', 'None')]
def queryset(self, request, queryset):
print self.lookup_val
print self.field.flatchoices
if self.lookup_val == '':
return queryset.filter(choice_field='')
else:
return queryset.filter(choice_field=self.lookup_val)
def choices(self, cl):
pass
and then in admin class
list_filter = [..., ('choice_field', ChoiceFieldFilter), ...]
but its not working, I'm unable to see None
filter in django admin
Upvotes: 5
Views: 5910
Reputation: 4453
By default the admin.AllValuesFieldListFilter return a value of a choice, not verbose name of the choice. So, for resolve it use the modified admin.AllValuesFieldListFilter.
class AllValuesChoicesFieldListFilter(admin.AllValuesFieldListFilter):
def choices(self, changelist):
yield {
'selected': self.lookup_val is None and self.lookup_val_isnull is None,
'query_string': changelist.get_query_string({}, [self.lookup_kwarg, self.lookup_kwarg_isnull]),
'display': _('All'),
}
include_none = False
# all choices for this field
choices = dict(self.field.choices)
for val in self.lookup_choices:
if val is None:
include_none = True
continue
val = smart_text(val)
yield {
'selected': self.lookup_val == val,
'query_string': changelist.get_query_string({
self.lookup_kwarg: val,
}, [self.lookup_kwarg_isnull]),
# instead code, display title
'display': choices[val],
}
if include_none:
yield {
'selected': bool(self.lookup_val_isnull),
'query_string': changelist.get_query_string({
self.lookup_kwarg_isnull: 'True',
}, [self.lookup_kwarg]),
'display': self.empty_value_display,
}
Usage:
list_filter = (
('country_origin', AllValuesChoicesFieldListFilter),
)
Upvotes: 3
Reputation: 1194
You don't have to make your custom list filter. Just use django's AllValuesFieldListFilter
from django.contrib.admin.filters import AllValuesFieldListFilter
...
list_filter = [..., ('choice_field', AllValuesFieldListFilter)]
...
Upvotes: 6