ModelAdmin Customization
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.
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.
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.
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. #}
- Editing Django's built-in admin templates directly instead of using ModelAdmin options to change behavior.
- Forgetting to register the customized ModelAdmin class, so the default admin interface is used instead.
- Putting business logic (like sending emails) inside save_model without calling super().save_model() first.
- 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.
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: