Django Admin Introduction
Django's administration interface is one of the framework's most powerful features that sets it apart from other web frameworks. The Django admin site provides a ready-to-use interface for managing your application's content, allowing you to perform CRUD (Create, Read, Update, Delete) operations on your data without writing any additional code.
What is Django Admin?
The Django admin is an automatic, model-centric interface where trusted users can manage your site's content. It reads metadata from your models to provide a quick, model-centric interface where authorized users can manage content on your site.
It's designed to be:
- Secure: Built with authorization and authentication systems
- Fast to set up: Often requiring just a few lines of code
- Customizable: Can be extended to suit your specific needs
Why Use Django Admin?
- Rapid development: Get a fully-functional admin interface with minimal code
- Database management: Easily manage your application's data through a web interface
- Content management: Allow non-technical team members to manage site content
- Prototyping: Quickly build and test models with immediate visual feedback
- Site maintenance: Perform administrative tasks without direct database access
Getting Started with Django Admin
Let's start with a simple example to understand how Django admin works. We'll create a simple blog application and configure the admin interface.
Step 1: Create a Django Project and App
If you haven't already, create a new Django project and app:
# Create a new Django project
django-admin startproject myproject
# Navigate to the project directory
cd myproject
# Create a new app called 'blog'
python manage.py startapp blog
Step 2: Add the App to Your Project
In myproject/settings.py
, add your app to the INSTALLED_APPS
list:
INSTALLED_APPS = [
'django.contrib.admin', # Django admin is already included by default
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog', # Add your blog app here
]
Step 3: Define Models
In blog/models.py
, define a simple blog post model:
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
class BlogPost(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True)
published_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)
is_published = models.BooleanField(default=False)
def __str__(self):
return self.title
Step 4: Register Models with the Admin Interface
Create or modify blog/admin.py
to register your models:
from django.contrib import admin
from .models import Category, BlogPost
# Basic registration
admin.site.register(Category)
admin.site.register(BlogPost)
Step 5: Create Database Tables and a Superuser
Run migrations to create your database tables:
python manage.py makemigrations
python manage.py migrate
Create a superuser to access the admin interface:
python manage.py createsuperuser
Follow the prompts to create a username, email address, and password.
Step 6: Run the Development Server
Start the development server:
python manage.py runserver
Now, visit http://localhost:8000/admin/
in your browser and log in with your superuser credentials.
Exploring the Admin Interface
After logging in, you'll see the Django admin dashboard with your registered models. Here's what you can do:
- Browse models: See all your registered models in the index page
- View records: Click on a model to see all its records in a list
- Add new records: Click "Add" to create new instances of a model
- Edit records: Click on any record to modify its fields
- Delete records: Select records and use the dropdown to delete them
- Filter and search: Use the filter sidebar and search box to find specific records
Enhancing the Admin Interface
The default admin interface is useful, but you can make it even better with some customizations:
Customizing the List Display
Let's improve how the blog posts are displayed in the admin:
from django.contrib import admin
from .models import Category, BlogPost
# Register Category model
admin.site.register(Category)
# Custom admin configuration for BlogPost
@admin.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'category', 'published_date', 'is_published')
list_filter = ('is_published', 'category', 'author')
search_fields = ('title', 'content')
date_hierarchy = 'published_date'
ordering = ('-published_date',)
Now the admin list view for BlogPost will show multiple columns, have filters, search capabilities, and date-based navigation.
Adding List Actions
You can add custom actions to the admin interface:
@admin.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'category', 'published_date', 'is_published')
list_filter = ('is_published', 'category', 'author')
search_fields = ('title', 'content')
date_hierarchy = 'published_date'
ordering = ('-published_date',)
actions = ['make_published', 'make_unpublished']
def make_published(self, request, queryset):
queryset.update(is_published=True)
make_published.short_description = "Mark selected posts as published"
def make_unpublished(self, request, queryset):
queryset.update(is_published=False)
make_unpublished.short_description = "Mark selected posts as unpublished"
Customizing Form Layout
You can control how the edit form is displayed:
@admin.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
fieldsets = (
('Post Information', {
'fields': ('title', 'content', 'category')
}),
('Publication Information', {
'fields': ('author', 'is_published'),
'classes': ('collapse',)
}),
)
Real-World Example: Managing a Blog Platform
Let's expand our blog application to include comments and tags, showing how Django admin can manage more complex relationships.
Extended Models
# blog/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)
description = models.TextField(blank=True)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
class Tag(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(unique=True)
def __str__(self):
return self.name
class BlogPost(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
content = models.TextField()
excerpt = models.TextField(blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True)
tags = models.ManyToManyField(Tag, blank=True)
featured_image = models.ImageField(upload_to='blog/images/', blank=True, null=True)
published_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True)
is_published = models.BooleanField(default=False)
views = models.PositiveIntegerField(default=0)
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(BlogPost, on_delete=models.CASCADE, related_name='comments')
name = models.CharField(max_length=100)
email = models.EmailField()
body = models.TextField()
created_date = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=False)
def __str__(self):
return f"Comment by {self.name} on {self.post.title}"
Enhanced Admin Configuration
# blog/admin.py
from django.contrib import admin
from .models import Category, Tag, BlogPost, Comment
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'slug')
prepopulated_fields = {'slug': ('name',)}
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
list_display = ('name', 'slug')
prepopulated_fields = {'slug': ('name',)}
class CommentInline(admin.TabularInline):
model = Comment
extra = 0
@admin.register(BlogPost)
class BlogPostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'category', 'is_published', 'published_date', 'views')
list_filter = ('is_published', 'category', 'author', 'tags')
search_fields = ('title', 'content', 'excerpt')
prepopulated_fields = {'slug': ('title',)}
date_hierarchy = 'published_date'
filter_horizontal = ('tags',)
readonly_fields = ('views', 'published_date', 'updated_date')
inlines = [CommentInline]
fieldsets = (
('Content', {
'fields': ('title', 'slug', 'content', 'excerpt', 'featured_image')
}),
('Classification', {
'fields': ('category', 'tags')
}),
('Publication', {
'fields': ('author', 'is_published', 'published_date', 'updated_date')
}),
('Metrics', {
'fields': ('views',),
'classes': ('collapse',)
}),
)
actions = ['make_published', 'make_unpublished']
def make_published(self, request, queryset):
rows_updated = queryset.update(is_published=True)
self.message_user(request, f"{rows_updated} posts were successfully marked as published.")
make_published.short_description = "Mark selected posts as published"
def make_unpublished(self, request, queryset):
rows_updated = queryset.update(is_published=False)
self.message_user(request, f"{rows_updated} posts were successfully marked as unpublished.")
make_unpublished.short_description = "Mark selected posts as unpublished"
@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_display = ('name', 'email', 'post', 'created_date', 'approved')
list_filter = ('approved', 'created_date')
search_fields = ('name', 'email', 'body')
actions = ['approve_comments', 'disapprove_comments']
def approve_comments(self, request, queryset):
queryset.update(approved=True)
approve_comments.short_description = "Approve selected comments"
def disapprove_comments(self, request, queryset):
queryset.update(approved=False)
disapprove_comments.short_description = "Disapprove selected comments"
This comprehensive configuration demonstrates how Django admin can handle complex data relationships, inline editing, custom actions, and more.
Summary
Django's admin interface is a powerful tool that:
- Provides immediate access to your application's data through a user-friendly interface
- Requires minimal setup for basic functionality
- Can be highly customized for specific needs
- Supports complex data relationships
- Offers features like filtering, searching, and custom actions
Whether you're building a simple application or a complex web platform, Django admin can significantly reduce the development time needed for management interfaces and provide immediate value to your project.
Additional Resources
Exercises
-
Basic Admin Setup: Create a simple movie database with models for movies, directors, and genres. Register them with the Django admin.
-
Custom List Display: Enhance your movie admin to show relevant information in the list view (release year, director, rating, etc.).
-
Admin Actions: Add a custom action to mark movies as "featured" or "classic".
-
Inline Editing: Set up the admin to allow adding cast members directly from the movie editing page.
-
Advanced Customization: Create a custom admin site theme by overriding Django admin templates and adding your own CSS.
By mastering Django admin, you'll have a powerful tool to manage your application's data efficiently while focusing more time on building your application's core features.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)