Skip to main content

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:

python
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:

bash
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:

python
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:

  1. A sidebar with your registered models grouped by app
  2. A main content area displaying records or actions
  3. Search functionality
  4. Filtering options
  5. Breadcrumb navigation

Example: Managing Blog Posts

Let's say we have a simple blog app with a Post model:

python
# 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:

python
# 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:

python
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.

If you have related models (like comments for blog posts), you can edit them inline:

python
# 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:

python
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:

html
{% 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:

python
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:

python
# 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:

python
# 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:

  1. Auto-populating slugs from titles/names
  2. Comprehensive list displays with filtering and search
  3. Inline editing of related models (images)
  4. Field grouping with fieldsets
  5. User-specific queryset filtering
  6. 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

Exercises

  1. Create a blog application with Post and Comment models, then customize the admin site to add inline editing of comments.

  2. Implement a custom admin action that can batch publish/unpublish selected posts.

  3. Override the admin templates to create a branded admin interface with your organization's colors and logo.

  4. Create a custom filter that allows filtering articles by word count or reading time.

  5. 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! :)