SimpleListFilter customizes a Django Admin sidebar filter when the default field values are too broad or unhelpful. It supplies selectable lookup links and applies the chosen value to the page’s QuerySet. section 5.2.2
A custom filter combines two attributes with two methods:
- Set title for the sidebar heading and parameter_name for the URL query parameter. section 5.2.2
- Implement lookups(request, model_admin) to return short URL values paired with user-facing labels. section 5.2.2
- Implement queryset(request, queryset) to read self.value(), preserve the original QuerySet when no choice is selected, and filter otherwise. section 5.2.2
Filtering musicians by birth decade
DecadeListFilter extends admin.SimpleListFilter with title = 'decade born' and parameter_name = 'decade'. Its lookups() creates decade choices from the current decade backward; queryset() converts the selected value to a year and filters birth__gte and birth__lte. With no selection, it returns the unfiltered QuerySet. section 5.2.2
Listing 5.4 Custom list filter based on decades
# RiffMates/bands/admin.py
...
from datetime import datetime, date #1
...
class DecadeListFilter(admin.SimpleListFilter): #2
title = 'decade born' #3
parameter_name = 'decade' #4
def lookups(self, request, model_admin):
result = []
this_year = datetime.today().year
this_decade = (this_year // 10) * 10 #5
start = this_decade - 10
for year in range(start, start - 100, -10): #6
result.append( (str(year), f"{year}-{year+9}") ) #7
return result
def queryset(self, request, queryset):
start = self.value() #8
if start is None:
return queryset
start = int(start)
result = queryset.filter(
birth__gte=date(start, 1, 1), #9
birth__lte=date(start + 9, 12, 31),
)
return result
...
class MusicianAdmin(admin.ModelAdmin):
list_display = ("id", "last_name", "first_name", "birth", #10
"show_weekday", )
list_filter = (DecadeListFilter, ) #11
Inspect the complete decade-based admin filter, including dynamic lookup generation and date-range filtering. section 5.2.2
