Mastering Django Inline Admin: TabularInline and StackedInline Examples
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
- Prerequisites
- Introduction to Django Inline Admin
- Setting Up the Django Project
- Creating Models
- Registering Models in Admin
- Using TabularInline
- Using StackedInline
- Customizing Inline Admin
- Enhancing Inline Admin with CSS and JavaScript
- Add Custom CSS and JavaScript
- 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)
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)
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)
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)
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.
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!');
});
}
});
});
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)
Run django collectstatic command and run server:
python manage.py collectstatic
python manage.py runserver
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.