- Published on
How to add Custom Filters to Django Admin? Also...
Overview
In this tutorial we'll cover following django admin customizations.
- Adding custom filters along with normal filters on your django admin table.
- Adding customize action button on admin table.
- Adding additional button on ModelAdmin form.
Custom Filters in Django admin
Django does a great job providing filters by default according to your model fields. But what if you need to add custom filter that can filter records according to your custom logic. Then you need to implement a custom filter and Django provide this capability out of the box.
Let's consider a table that store Starwars characters having mass
as one of the fields and you want to filter the characters by mass category for example, light, heavy, super heavy etc.
@admin.register(models.Characters)
class CharactersAdmin(ImportExportModelAdmin, admin.ModelAdmin):
list_display = ("name", "birth_year", "gender", "mass")
list_filter = (WeightFilter, "gender", "hair_color")
...
Then you have to implement a class with name WeightFilter
in the following way.
class WeightFilter(admin.SimpleListFilter):
title = "By Weight"
parameter_name = "weight"
def lookups(self, request, model_admin):
return [('light', 'Light'), ('heavy', 'Heavy'), ('super_heavy', 'Super Heavy')]
def queryset(self, request, queryset):
if self.value() == 'light':
return queryset.filter(mass__lte=50.0)
if self.value() == 'heavy':
return queryset.filter(mass__range=(51.0, 100.0))
if self.value() == 'super_heavy':
return queryset.filter(mass__gte=101.0)
return queryset
The final result would look something like this.
Custom Action Buttons on Django admin.
You can easily customize your admin to add custom button at top right corner beside Add object button. You can also add url
to those buttons and perform some action on them. Let's see how to do it.
Add the following file in your templates.
{% extends "admin/change_list.html" %}
{% load i18n static %}
{% block object-tools-items %}
<li>
<a href="attack/">Attack</a>
</li>
<li>
<a href="defend/">Defend</a>
</li>
{{ block.super }}
{% endblock %}
Then in your admin class add following methods.
@admin.register(models.Characters)
class CharactersAdmin(ImportExportModelAdmin, admin.ModelAdmin):
list_display = ("name", "birth_year", "gender", "mass")
list_filter = (WeightFilter, "gender", "hair_color")
change_list_template = "admin/characters_changelist.html"
def get_urls(self):
# additional urls
from django.urls import path
urls = super().get_urls()
my_urls = [
path('attack/', self.attack),
path('defend/', self.defend),
]
return my_urls + urls
def attack(self, request):
# custom operation
print("attack")
return HttpResponseRedirect("../")
def defend(self, request):
# custom operation
print("defend")
return HttpResponseRedirect("../")
...
The final result would look something like this.
Additional Buttons in ModelAdmin form.
Now let's say you need add custom buttons at the end regular model form to have extra functionaly then you can customize change_form_template
like following.
{% extends "admin/change_form.html" %}
{% load admin_modify %}
{% load i18n admin_urls%}
{% block submit_buttons_bottom %}
{% submit_row %}
<input type="submit" value="Power Up" name="_powerup" />
<input type="submit" value="Heal" name="_heal" />
{% endblock %}
Then to listen to submit events, head over to your admin class.
@admin.register(models.Characters)
class CharactersAdmin(ImportExportModelAdmin, admin.ModelAdmin):
list_display = ("name", "birth_year", "gender", "mass")
list_filter = (WeightFilter, "gender", "hair_color")
change_form_template = "admin/characters_change_form.html"
def save_model(self, request, obj, form, changed):
if '_powerup' in request.POST:
print("Power Up")
messages.success(request, "Powered Up successfully!")
if '_heal' in request.POST:
print("Heal")
messages.success(request, "Healed successfully!")
obj.save()
...
The final result would look something like this.
Conclusion
We saw how can we easily customize few aspects of django admin and make our lives easier while performing admin operations. I hope you have learned some new things from this article and if you do then please drop a like and share with your colleagues and friends. See you in the next one 👋!