← Back to Django Course | Chapter 8: Django Admin | Lesson 6 of 8

ModelAdmin Customization

A ModelAdmin class is where you fine-tune exactly how one model looks and behaves inside the admin dashboard.

Why Use a ModelAdmin Subclass

admin.site.register(Model) alone gives you Django's defaults. To change ordering, add read-only fields, or hook into saving, you subclass admin.ModelAdmin and register that instead.

Example: Why Use a ModelAdmin Subclass

Shows the newest books first in the admin list page.

markup
from django.contrib import admin
from .models import Book

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    ordering = ('-published_date',)
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Making Fields Read-Only

readonly_fields lists fields that still appear on the add/edit form but can't be changed there -- useful for timestamps or computed values.

Example: Making Fields Read-Only

created_at is displayed on the edit form but grayed out and non-editable.

markup
class BookAdmin(admin.ModelAdmin):
    readonly_fields = ('created_at',)
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Hooking Into save_model

Overriding save_model() lets you run code every time a record is saved from the admin, as long as you still call the parent implementation to actually persist it.

Warning: Skipping super().save_model(request, obj, form, change) means the object is never actually saved to the database.

Example: Hooking Into save_model

Trims whitespace from the title every time a Book is saved through the admin.

markup
class BookAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.title = obj.title.strip()
        super().save_model(request, obj, form, change)
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Editing Django's built-in admin templates directly instead of using ModelAdmin options to change behavior.
  2. Forgetting to register the customized ModelAdmin class, so the default admin interface is used instead.
  3. Putting business logic (like sending emails) inside save_model without calling super().save_model() first.
Chapter Summary
  • ModelAdmin subclasses let you configure list_display, search_fields, list_filter, ordering, and more for one model.
  • readonly_fields marks fields that show on the form but can't be edited.
  • Overriding save_model() lets you hook custom logic into the admin's save action.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.