Mastering Django Inline Admin: TabularInline and StackedInline Examples

Mehedi Khan
Django Unleashed
Published in
5 min readJul 12, 2024
Django Inline Admin: TabularInline and StackedInline

Django’s admin interface is a powerful tool for managing your application’s data. One of its most useful features is the ability to edit related models on the same page using inline model admin classes. In this tutorial, we’ll cover how to use TabularInline and StackedInline with detailed examples.

Table of Contents

  1. Prerequisites
  2. Introduction to Django Inline Admin
  3. Setting Up the Django Project
  4. Creating Models
  5. Registering Models in Admin
  6. Using TabularInline
  7. Using StackedInline
  8. Customizing Inline Admin
  9. Enhancing Inline Admin with CSS and JavaScript
  10. Add Custom CSS and JavaScript
  11. Conclusion

Prerequisites

  • Python 3.8 or higher
  • Django 4.0 or higher

Introduction to Django Inline Admin

Django inline admin classes (TabularInline and StackedInline) allow us to add related models data on the same page. This is particularly useful for models with foreign key relationships.

Setting Up the Django Project

First, ensure you have Django installed. Create a new Django project and app:

django-admin startproject myproject
cd myproject
django-admin startapp myapp

Add myapp to your INSTALLED_APPS in settings.py:

# settings.py

INSTALLED_APPS = [
# ...
'myapp',
]

Creating Models

Create two models, Author and Book, where each book has a foreign key to an author.

# myapp/models.py

from django.db import models

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

def __str__(self):
return self.name


class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
publication_date = models.DateField()

def __str__(self):
return self.title

Run migrations to create the database tables:

python manage.py makemigrations
python manage.py migrate

Registering Models in Admin

Next, register the models in the Django admin site:

# myapp/admin.py

from django.contrib import admin
from .models import Author, Book


admin.site.register(Author)
admin.site.register(Book)
django admin panel

Using TabularInline

To use TabularInline, create an inline class and associate it with the parent model:

# myapp/admin.py

from django.contrib import admin
from .models import Author, Book


class BookInline(admin.TabularInline):
model = Book
extra = 2 # Number of extra forms to display


class AuthorAdmin(admin.ModelAdmin):
inlines = [BookInline]


admin.site.register(Author, AuthorAdmin)
admin.site.register(Book)
Django TabularInline admin panel

With this setup, you can add and edit books directly on the author’s admin page.

Using StackedInline

To use StackedInline, simply replace TabularInline with StackedInline:

# myapp/admin.py

from django.contrib import admin
from .models import Author, Book

class BookInline(admin.StackedInline):
model = Book
extra = 2 # Number of extra forms to display


class AuthorAdmin(admin.ModelAdmin):
inlines = [BookInline]


admin.site.register(Author, AuthorAdmin)
admin.site.register(Book)
Django StackedInline admin panel

StackedInline provides a more detailed layout compared to TabularInline.

Customizing Inline Admin

You can further customize the inline admin form by specifying fields, setting read-only fields, or adding custom methods:

# myapp/admin.py

from django.contrib import admin
from .models import Author, Book


class BookInline(admin.TabularInline):
model = Book
extra = 2 # Number of extra forms to display
fields = ['title', 'publication_date'] # Specify fields to display
readonly_fields = ['publication_date'] # Make certain fields read-only

def some_custom_method(self, obj):
# Custom method to display extra information
return obj.title

class AuthorAdmin(admin.ModelAdmin):
inlines = [BookInline]


admin.site.register(Author, AuthorAdmin)
admin.site.register(Book)
Django Customizing Inline Admin panel

Enhancing Inline Admin with CSS and JavaScript

You might want to include custom CSS or JavaScript to enhance the inline admin interface:

# myapp/admin.py
class BookInline(admin.TabularInline):
model = Book
extra = 1

class Media:
css = {
'all': ('css/custom_admin.css',) # Include custom CSS
}
js = ('js/custom_admin.js',) # Include custom JavaScript

class AuthorAdmin(admin.ModelAdmin):
inlines = [BookInline]

Place your custom CSS and JavaScript files in the appropriate static directories.

Enhancing django Inline Admin with CSS and JavaScript

Add Custom CSS and JavaScript

To add custom CSS and JavaScript, you need to override the default admin templates.

Create directories for your static files like css and js:

mkdir staticfiles\css 
mkdir staticfiles\js
mkdir static

Add your custom CSS and JavaScript.

staticfiles/css/custom_admin.css:

/* Example: Change background color of the inline forms */
.inline-related {
background-color: #f9f9f9;
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
}

staticfiles/js/custom_admin.js:

document.addEventListener('DOMContentLoaded', function() {
// Example: Add event listener to a button inside the inline form
document.querySelectorAll('.inline-related').forEach(function(inline) {
var deleteButton = inline.querySelector('.delete');
if (deleteButton) {
deleteButton.addEventListener('click', function() {
alert('You are about to delete a book!');
});
}
});
});
Django Add Custom CSS and JavaScript

Update Settings and urls.py files

Ensure Django knows where to find your static files and templates.

myproject/settings.py:

# myproject/settings.py

# template
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]


# Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'static'

STATICFILES_DIRS = [
BASE_DIR / 'staticfiles',
]

myproject/urls.py:

# myproject/urls.py

from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static


urlpatterns = [
path('admin/', admin.site.urls),
]

if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)
django update Settings and urls.py files

Run django collectstatic command and run server:

python manage.py collectstatic

python manage.py runserver
Run django collectstatic command and run server

Conclusion

Using Django’s TabularInline and StackedInline classes, you can create a more efficient and user-friendly admin interface for managing related models. Customize the inline forms to suit your project's needs and enhance the admin experience with additional CSS and JavaScript if necessary.

Thank you for reading! If you notice any mistakes or have suggestions for improvement, please leave a comment below.

If you enjoyed this post, please click the 👏 button to help others discover it. You can also follow me on:

GitHub | daily.dev | LinkedIn | YouTube

More library

Django

27 stories

--

--

Mehedi Khan
Django Unleashed

I'm a Software engineer. I'm comfortable with Python, Django, and Full-stack Web Development. Follow To Support Me On Medium 🫠