Django Admin Site
The Django admin site is one of the most powerful features of Django, providing a ready-to-use interface for managing your application's data. It's essentially a web-based dashboard that allows developers and site administrators to create, read, update, and delete records in your database without writing any additional code.
Introduction to Django Admin
Django's admin interface is often described as Django's "killer feature" because it automatically generates a user interface for your models, saving you the time and effort of creating a custom administrative interface from scratch. It's designed to be:
- Secure: It includes authentication, authorization, and protection against common attacks
- Customizable: You can tailor it to your project's specific needs
- Productive: It enables content managers to start working with your data immediately
Getting Started with Django Admin
Prerequisites
Before diving in, ensure you have:
- Django installed (
pip install django
) - A Django project created
- At least one app with models defined
Enabling the Admin Site
The admin site comes enabled in new Django projects by default. If you check your project's urls.py
file, you should see:
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
# Your other URL patterns...
]
This means the admin interface is available at the /admin/
URL of your application.
Creating a Superuser
To access the admin site, you need to create a superuser account:
python manage.py createsuperuser
Follow the prompts to set a username, email, and password. These credentials will be used to log in to the admin site.
Registering Models in Admin
To manage models through the admin interface, you need to register them. In your app's admin.py
file:
from django.contrib import admin
from .models import Book, Author
admin.site.register(Book)
admin.site.register(Author)
Now your Book
and Author
models will appear in the admin interface.
Basic Admin Interface Features
After logging in to http://localhost:8000/admin/
(assuming you're using the development server), you'll see:
- A sidebar with your registered models grouped by app
- A main content area displaying records or actions
- Search functionality
- Filtering options
- Breadcrumb navigation
Example: Managing Blog Posts
Let's say we have a simple blog app with a Post
model:
# blog/models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
pub_date = models.DateTimeField('date published')
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
After registering this model in admin.py
, you can:
- View all posts in a list
- Search posts by title
- Filter posts by publication date
- Add new posts
- Edit existing posts
- Delete posts
Customizing the Admin Interface
Custom Model Admin Classes
For more control over how your models appear in the admin, create a custom ModelAdmin
class:
# blog/admin.py
from django.contrib import admin
from .models import Post
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'pub_date', 'author')
list_filter = ['pub_date', 'author']
search_fields = ['title', 'content']
date_hierarchy = 'pub_date'
ordering = ['-pub_date']
admin.site.register(Post, PostAdmin)
This customization:
- Shows title, publication date, and author in the list view
- Adds filters for publication date and author
- Enables searching by title and content
- Adds date-based navigation
- Orders posts with newest first
Fieldsets for Form Organization
Group related fields together using fieldsets:
class PostAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['title']}),
('Content', {'fields': ['content']}),
('Publication info', {'fields': ['pub_date', 'author'], 'classes': ['collapse']}),
]
# rest of the configuration...
The 'collapse' class makes the "Publication info" section collapsible.
Inlines for Related Models
If you have related models (like comments for blog posts), you can edit them inline:
# blog/models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
author = models.CharField(max_length=100)
text = models.TextField()
def __str__(self):
return f"Comment by {self.author}"
# blog/admin.py
class CommentInline(admin.TabularInline): # or admin.StackedInline
model = Comment
extra = 1 # Number of empty forms to display
class PostAdmin(admin.ModelAdmin):
inlines = [CommentInline]
# rest of the configuration...
Now when editing a post, you'll see forms for adding comments directly on the post's page.
Advanced Admin Customizations
Custom Actions
Add custom actions to perform operations on multiple records at once:
class PostAdmin(admin.ModelAdmin):
actions = ['make_published', 'make_draft']
def make_published(self, request, queryset):
queryset.update(status='published')
make_published.short_description = "Mark selected posts as published"
def make_draft(self, request, queryset):
queryset.update(status='draft')
make_draft.short_description = "Mark selected posts as drafts"
Custom Admin Templates
You can override the default templates used by the admin site. Create a directory structure like:
templates/
admin/
base_site.html # To customize the admin site header
index.html # To customize the admin home page
app_name/
model_name/
change_form.html # To customize the edit page for a specific model
Then add this template directory to your TEMPLATES
setting in settings.py
.
Example base_site.html
to customize the header:
{% extends "admin/base_site.html" %}
{% block title %}{{ title }} | My Custom Admin Site{% endblock %}
{% block branding %}
<h1 id="site-name">
<a href="{% url 'admin:index' %}">My Blog Administration</a>
</h1>
{% endblock %}
Admin Site Permissions
Django's admin site uses the permission system to control access:
class PostAdmin(admin.ModelAdmin):
def has_change_permission(self, request, obj=None):
# Only allow editing of posts by their authors
if obj and obj.author != request.user:
return False
return True
Real-World Example: Content Management System
Let's build a more complete example for a content management system:
# cms/models.py
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
class Article(models.Model):
STATUS_CHOICES = [
('draft', 'Draft'),
('published', 'Published'),
]
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
content = models.TextField()
summary = models.TextField(blank=True)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
class Image(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='images')
image = models.ImageField(upload_to='articles/')
caption = models.CharField(max_length=200, blank=True)
def __str__(self):
return self.caption or f"Image for {self.article.title}"
And now let's create a comprehensive admin configuration:
# cms/admin.py
from django.contrib import admin
from django.utils.html import format_html
from .models import Category, Article, Image
class CategoryAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("name",)}
list_display = ('name', 'slug')
search_fields = ('name',)
class ImageInline(admin.TabularInline):
model = Image
extra = 1
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
list_display = ('title', 'author', 'category', 'status', 'created', 'updated')
list_filter = ('status', 'category', 'author', 'created')
search_fields = ('title', 'content', 'summary')
date_hierarchy = 'created'
inlines = [ImageInline]
fieldsets = [
('Basic Information', {
'fields': ['title', 'slug', 'author', 'category']
}),
('Content', {
'fields': ['summary', 'content']
}),
('Publishing', {
'fields': ['status'],
'classes': ['collapse']
})
]
# Only show articles by the current user unless they're superusers
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)
# Auto-set the author field to the current user
def save_model(self, request, obj, form, change):
if not obj.author_id:
obj.author = request.user
super().save_model(request, obj, form, change)
admin.site.register(Category, CategoryAdmin)
This example demonstrates:
- Auto-populating slugs from titles/names
- Comprehensive list displays with filtering and search
- Inline editing of related models (images)
- Field grouping with fieldsets
- User-specific queryset filtering
- Auto-setting fields during save
Summary
The Django admin site is a powerful tool that can significantly speed up your development process. With minimal setup, it provides a fully-functional interface for managing your application's data. Through customization options like ModelAdmin
classes, actions, and template overrides, you can tailor it to meet the specific needs of your project.
Some key benefits of the Django admin site:
- Rapid development of administrative interfaces
- Automatic form generation based on your models
- Built-in security features
- Extensive customization options
- Productivity boost for content managers
While the admin site is not typically intended for end-users, it's perfect for site administrators, content editors, and developers who need to manage application data.
Additional Resources
- Official Django Admin Documentation
- Django Admin Cookbook - Advanced admin customization techniques
- Django Admin Interface - A third-party package for enhancing the admin UI
Exercises
-
Create a blog application with
Post
andComment
models, then customize the admin site to add inline editing of comments. -
Implement a custom admin action that can batch publish/unpublish selected posts.
-
Override the admin templates to create a branded admin interface with your organization's colors and logo.
-
Create a custom filter that allows filtering articles by word count or reading time.
-
Implement field-level permissions so that only certain users can edit specific fields in a model.
If you spot any mistakes on this website, please let me know at feedback@compilenrun.com. I’d greatly appreciate your feedback! :)