Skip to main content

Django Admin Styling

Introduction

The Django Admin interface provides a powerful out-of-the-box solution for managing your application's data. While the default styling is functional, you may want to customize its appearance to match your project's branding or improve the user experience for administrators. In this tutorial, we'll explore various techniques to style and customize the Django Admin interface.

Understanding Django Admin Templates

Django's admin interface is built using Django's template system. The admin templates are located in the Django source code, but you can override them in your project. Before diving into styling, it's important to understand the template hierarchy.

Default Admin Template Structure

The admin templates are located within Django's installation directory, typically at:

django/contrib/admin/templates/admin/

Common templates include:

  • base_site.html - The main template for the admin site
  • index.html - The admin homepage
  • change_list.html - List view of model instances
  • change_form.html - Form for adding/editing model instances

Basic Admin Customization

1. Changing the Admin Site Title and Header

The simplest customization is changing the admin site title and header. You can do this in your project's admin.py:

python
from django.contrib import admin

# Customize admin site title and header
admin.site.site_header = "My Project Admin"
admin.site.site_title = "My Project Admin Portal"
admin.site.index_title = "Welcome to My Project Admin Portal"

Result: This changes the text in the admin interface from "Django Administration" to your custom titles.

2. Creating a Custom base_site.html

To make more substantial changes to the admin interface, create a custom base_site.html:

  1. Create the directory structure in your project:
your_project/
templates/
admin/
base_site.html
  1. Add the template directory to your TEMPLATES setting in settings.py:
python
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # Add this line
'APP_DIRS': True,
# ... other settings
},
]
  1. Create your custom base_site.html:
html
{% extends "admin/base.html" %}
{% load static %}

{% block title %}{{ title }} | {{ site_title|default:_('My Custom Admin') }}{% endblock %}

{% block branding %}
<h1 id="site-name">
<a href="{% url 'admin:index' %}">
<img src="{% static 'img/logo.png' %}" height="40px" alt="Logo" />
{{ site_header|default:_('My Company Administration') }}
</a>
</h1>
{% endblock %}

{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'css/admin-style.css' %}" />
{% endblock %}

Adding Custom CSS Styles

1. Create a Custom CSS File

Create a CSS file in your static directory:

your_project/
static/
css/
admin-style.css

Add your custom styles to admin-style.css:

css
/* Primary branding colors */
:root {
--primary: #5b21b6;
--secondary: #8b5cf6;
--accent: #c4b5fd;
--dark-bg: #1f2937;
--light-text: #f9fafb;
}

/* Header styling */
#header {
background: var(--primary);
color: var(--light-text);
}

/* Link colors */
a:link, a:visited {
color: var(--secondary);
}

/* Button styling */
.button, input[type=submit], input[type=button], .submit-row input, a.button {
background: var(--primary);
color: var(--light-text);
}

.button:hover, input[type=submit]:hover, input[type=button]:hover {
background: var(--secondary);
}

/* Selected rows */
.selected {
background-color: var(--accent) !important;
}

/* Module styling */
.module h2, .module caption, .inline-group h2 {
background-color: var(--primary);
}

2. Configure Static Files

Make sure your settings.py has the correct static files configuration:

python
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]

Advanced Admin Styling

1. Custom Admin Theme with Django Jazzmin

For a more complete admin theme, consider using packages like Django Jazzmin. Install it with pip:

pip install django-jazzmin

Add it to your INSTALLED_APPS in settings.py (before django.contrib.admin):

python
INSTALLED_APPS = [
'jazzmin',
# ... Django's default apps
'django.contrib.admin',
# ... your apps
]

Configure Jazzmin in your settings.py:

python
JAZZMIN_SETTINGS = {
"site_title": "My Project Admin",
"site_header": "My Project",
"site_brand": "My Project",
"site_logo": "img/logo.png",
"login_logo": "img/login-logo.png",
"site_icon": "img/favicon.ico",
"welcome_sign": "Welcome to My Project Admin",
"copyright": "My Company Ltd",
"custom_css": "css/admin-style.css",
"custom_js": "js/admin-script.js",
"show_ui_builder": True,
"topmenu_links": [
{"name": "Home", "url": "admin:index", "permissions": ["auth.view_user"]},
{"name": "View Site", "url": "/", "new_window": True},
],
"usermenu_links": [
{
"name": "Support",
"url": "https://example.com/support/",
"new_window": True,
},
],
"icons": {
"auth.user": "fas fa-user",
"auth.group": "fas fa-users",
},
"default_icon_parents": "fas fa-folder",
"default_icon_children": "fas fa-file",
"themes": [
{
"theme": "default",
"color": "#5b21b6",
"dark_mode": False,
},
{
"theme": "darkly",
"color": "#8B5CF6",
"dark_mode": True,
},
],
}

2. Customizing Admin List Display

You can customize how model lists appear in the admin by using CSS classes in your ModelAdmin classes:

python
from django.contrib import admin
from .models import Product

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ('name', 'price', 'stock_status')
list_display_links = ('name',)

def stock_status(self, obj):
if obj.stock <= 0:
return format_html('<span class="out-of-stock">Out of Stock</span>')
elif obj.stock < 10:
return format_html('<span class="low-stock">Low Stock ({0})</span>', obj.stock)
else:
return format_html('<span class="in-stock">In Stock ({0})</span>', obj.stock)

stock_status.short_description = 'Stock Status'

class Media:
css = {
'all': ('css/admin/product.css',)
}

Then, create static/css/admin/product.css:

css
.out-of-stock {
color: #fff;
background-color: #dc2626;
padding: 3px 8px;
border-radius: 4px;
}

.low-stock {
color: #fff;
background-color: #f59e0b;
padding: 3px 8px;
border-radius: 4px;
}

.in-stock {
color: #fff;
background-color: #10b981;
padding: 3px 8px;
border-radius: 4px;
}

Practical Example: Building a Branded Admin Interface

Let's create a complete example of a branded admin interface for a fictional company called "GreenTech Solutions":

Step 1: Create the Basic Structure

Create the necessary directories and files:

your_project/
templates/
admin/
base_site.html
static/
admin/
css/
custom_admin.css
img/
greentech-logo.png
favicon.ico

Step 2: Customize base_site.html

html
{% extends "admin/base.html" %}
{% load static %}

{% block title %}{{ title }} | {{ site_title|default:_('GreenTech Admin') }}{% endblock %}

{% block extrahead %}
{{ block.super }}
<link rel="shortcut icon" href="{% static 'admin/img/favicon.ico' %}" />
{% endblock %}

{% block branding %}
<h1 id="site-name">
<a href="{% url 'admin:index' %}">
<img src="{% static 'admin/img/greentech-logo.png' %}" height="40px" alt="GreenTech Logo" />
<span>GreenTech Solutions Admin</span>
</a>
</h1>
{% endblock %}

{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/custom_admin.css' %}" />
{% endblock %}

{% block nav-global %}
<div class="admin-help-links">
<a href="https://docs.example.com" target="_blank">Documentation</a> |
<a href="https://support.example.com" target="_blank">Support</a>
</div>
{% endblock %}

Step 3: Create Custom CSS

In static/admin/css/custom_admin.css:

css
:root {
--primary-color: #166534;
--secondary-color: #22c55e;
--light-green: #dcfce7;
--dark-text: #1e293b;
--light-text: #f8fafc;
}

/* Header styling */
#header {
background: var(--primary-color);
color: var(--light-text);
height: 70px;
padding: 10px 20px;
}

#header a:link, #header a:visited {
color: var(--light-text);
}

#site-name a {
display: flex;
align-items: center;
font-size: 20px;
}

#site-name img {
margin-right: 10px;
}

/* Module styling */
.module h2, .module caption, .inline-group h2 {
background-color: var(--primary-color);
}

/* Button styling */
.button, input[type=submit], input[type=button], .submit-row input, a.button {
background: var(--primary-color);
color: var(--light-text);
padding: 8px 15px;
border-radius: 4px;
}

.button:hover, input[type=submit]:hover, input[type=button]:hover {
background: var(--secondary-color);
}

.button.default, input[type=submit].default {
background: var(--secondary-color);
font-weight: bold;
}

.button.default:hover, input[type=submit].default:hover {
background: var(--primary-color);
}

/* Dashboard customization */
.dashboard .module table th {
background-color: var(--light-green);
color: var(--dark-text);
}

.dashboard .module table tr:nth-child(odd) {
background-color: #f9f9f9;
}

/* Login screen customization */
.login {
background: linear-gradient(135deg, var(--light-green), #f0fdf4);
}

.login #header {
background: transparent;
}

.login #header h1 {
color: var(--primary-color);
}

.admin-help-links {
float: right;
margin-right: 20px;
margin-top: -30px;
color: var(--light-text);
}

.admin-help-links a {
margin: 0 5px;
color: var(--light-text) !important;
}

/* Form styling */
fieldset.module {
border: 1px solid #e5e7eb;
border-radius: 6px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
margin-bottom: 20px;
}

.form-row {
padding: 12px;
border-bottom: 1px solid #f1f1f1;
}

/* Make tables more readable */
table {
border-collapse: separate;
border-spacing: 0;
border-radius: 6px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}

thead th {
background: var(--light-green);
color: var(--dark-text);
font-weight: 600;
}

/* Pagination */
.paginator a:link, .paginator a:visited {
background: var(--primary-color);
color: white;
padding: 4px 8px;
border-radius: 4px;
}

.paginator a:hover {
background: var(--secondary-color);
}

Step 4: Configure in Settings

Update your settings.py:

python
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(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',
],
},
},
]

STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]

STATIC_URL = '/static/'

# Admin site customization
ADMIN_SITE_HEADER = "GreenTech Solutions Admin"
ADMIN_SITE_TITLE = "GreenTech Admin Portal"
ADMIN_INDEX_TITLE = "Welcome to GreenTech Admin"

Step 5: Update urls.py

python
from django.contrib import admin
from django.urls import path, include
from django.conf import settings

admin.site.site_header = settings.ADMIN_SITE_HEADER
admin.site.site_title = settings.ADMIN_SITE_TITLE
admin.site.index_title = settings.ADMIN_INDEX_TITLE

urlpatterns = [
path('admin/', admin.site.urls),
# ... your other URL patterns
]

Summary

In this tutorial, we've covered various ways to style and customize the Django admin interface:

  1. Basic customization - Changing titles, headers, and basic branding
  2. Template overriding - Creating custom admin templates
  3. CSS styling - Adding custom stylesheets to modify the admin appearance
  4. Third-party packages - Using packages like Django Jazzmin for comprehensive theming
  5. Practical example - Building a complete branded admin interface

Customizing the Django admin interface helps create a more cohesive user experience for administrators and can better reflect your project's branding. By using the techniques in this tutorial, you can transform the default admin interface into something that feels like an integral part of your application.

Additional Resources

Exercises

  1. Beginner: Customize the Django admin site title and header for your project.
  2. Intermediate: Create a custom CSS file to change the color scheme of the admin interface.
  3. Advanced: Override the base_site.html template to add your logo and custom navigation links.
  4. Expert: Create a fully branded admin interface for a fictional company, including custom CSS, templates, and model admin customizations.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)