Mastering Custom Admin Filter in Django

Introduction

Django’s admin interface is a powerful tool for managing your application’s data. Sometimes, you may need to filter the choices available in foreign key field based on the selection of another foreign key field. In this blog post, we’ll walk through the process of creating custom admin filters to achieve this in a Django admin site.

adding custom filters to django admin is easy

Step 1: Create a Django Project and Define Your Models

Before we begin, make sure you have a Django project with the necessary models defined. For this example, we’ll create two models: Author and Book, with a Publisher foreign key field in the Book model.

# models.py
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE)

class Publisher(models.Model):
    name = models.CharField(max_length=100)

Step 2: Create a Custom Admin Filter

To filter the available publishers in Book model based on the selected author, you need to create an custom admin filter. Define a class that extends admin.SimpleListFilter in the admin.py file.

# admin.py
from django.contrib import admin
from .models import Book

class PublisherFilter(admin.SimpleListFilter):
    title = 'Publisher'
    parameter_name = 'publisher_id'

    def lookups(self, request, model_admin):
        # Get distinct publisher values based on the selected author
        author_id = request.GET.get('author__id')
        if author_id:
            return Book.objects.filter(author_id=author_id).values_list('publisher__id', 'publisher__name').distinct()
        else:
            return []

    def queryset(self, request, queryset):
        # Filter the queryset based on the selected publisher
        publisher_id = self.value()
        if publisher_id:
            return queryset.filter(publisher_id=publisher_id)
        else:
            return queryset

Step 3: Add the Custom Filter to the Admin

Next, add the custom filter to the list_filter attribute of the BookAdmin class.

class BookAdmin(admin.ModelAdmin):
    list_filter = (PublisherFilter,)

admin.site.register(Book, BookAdmin)

Step 4: Run the Development Server

Now, run your Django development server and access the admin interface. You’ll see the Publisher filter in the Book list view. When you select an Author, the available Publishers will be filtered based on the author’s books.

Conclusion

In this blog post, we’ve learned filtering the choices in a foreign key field in the Django admin based on the selection of another foreign key field. Custom admin filters provide a powerful way to enhance the functionality of the Django admin interface and make data management more efficient.

For More Info : https://docs.djangoproject.com/en/4.2/