Rohan Yeole - HomepageRohan Yeole

Automatically Register All Models In Django Admin

By Rohan Yeole
Table of Contents

When working on a content-heavy Django project, I found myself constantly repeating the same code in admin.py — list_display, search_fields, and more. 

I thought: what if Django could figure this out on its own?
So I built a reusable utility that does exactly that.

Let me walk you through it — and give you the full code so you can plug it into your own project.

The Utility: auto_admin.py

Save this file as auto_admin.py in your project (e.g., inside a utils/ or core/ folder).

from django.contrib import admin
from django.db import models

def generate_auto_admin(model):
meta = model._meta
fields = [f for f in meta.fields]

list_display = [f.name for f in fields if not isinstance(f, models.TextField)]
search_fields = [f.name for f in fields if isinstance(f, (models.CharField, models.TextField))]
list_filter = [f.name for f in fields if isinstance(f, (models.BooleanField, models.DateField, models.ForeignKey))]
ordering = ['-id'] if any(f.name == 'id' for f in fields) else None
readonly_fields = [f.name for f in fields if not f.editable]
prepopulated_fields = {}

for f in fields:
if isinstance(f, models.SlugField):
for src in fields:
if isinstance(src, models.CharField) and src.name != f.name:
prepopulated_fields[f.name] = (src.name,)
break

date_hierarchy = next((name for name in ['created_at', 'published_at', 'date'] if name in [f.name for f in fields]), None)

admin_attrs = {
"list_display": list_display,
"search_fields": search_fields,
"list_filter": list_filter,
"ordering": ordering,
"readonly_fields": readonly_fields,
"date_hierarchy": date_hierarchy,
}

if prepopulated_fields:
admin_attrs["prepopulated_fields"] = prepopulated_fields

return type(f"{model.__name__}AutoAdmin", (admin.ModelAdmin,), admin_attrs)

How to Use It in admin.py

Now in your admin.py, import the generator and register your models like this:

from django.contrib import admin
from django.apps import apps
from .utils.auto_admin import generate_auto_admin # adjust path accordingly

app_models = apps.get_app_config('your_app_name').get_models()

for model in app_models:
try:
admin.site.register(model, generate_auto_admin(model))
except admin.sites.AlreadyRegistered:
pass

Just replace 'your_app_name' with the name of your app. This loop will automatically register all models using their dynamic ModelAdmin classes.

Why This Works

In regular Python, class variables like list_display = list_display won’t work if list_display is defined outside the class. But using type() like this:

type("MyAdmin", (admin.ModelAdmin,), {"list_display": [...], ...})

We bypass that issue by dynamically injecting attributes directly into the class definition at runtime.

This small utility has saved me hours of repetitive admin setup. And because it’s introspection-based, it scales beautifully across apps and teams — without sacrificing readability or maintainability.

Try it in your own project, and let me know how it goes.

Need more admin power tips? Check out this explore Search and tutorials to supercharge your app.