Admin Interface
The Django-CFG sample project showcases a modern, customizable admin interface built on the Unfold theme. This guide covers admin customization, dashboard widgets, and navigation configuration.
Unfold Theme Integration
The sample project uses the Unfold theme for a modern, Material Design-inspired admin interface.
Theme Configuration
Configure the theme in api/config.py:
from django_cfg import (
UnfoldConfig, UnfoldColors, UnfoldSidebar,
NavigationSection, NavigationItem, Icons,
)
unfold: UnfoldConfig = UnfoldConfig(
site_title="Django-CFG Sample Admin",
site_header="Django-CFG Sample",
site_url="/",
site_symbol=Icons.ROCKET_LAUNCH,
colors=UnfoldColors(primary="#4F46E5"),
sidebar=UnfoldSidebar(
show_search=True,
show_all_applications=True,
),
navigation=[...], # NavigationSection list
)Theme Options
Basic Settings
UnfoldConfig(
site_title="My Admin", # Browser tab title
site_header="My Site Admin", # Admin header text
site_url="/", # Logo link URL
site_symbol=Icons.DASHBOARD, # Material icon name
)Colors
Customize the color scheme using UnfoldColors:
from django_cfg import UnfoldColors
UnfoldConfig(
colors=UnfoldColors(primary="#4F46E5"),
)Navigation Structure
Custom Navigation
Define a custom navigation menu using typed NavigationSection and NavigationItem objects:
from django_cfg import (
UnfoldConfig, NavigationSection, NavigationItem, Icons,
)
unfold: UnfoldConfig = UnfoldConfig(
navigation=[
NavigationSection(
title="Content Management",
separator=True,
items=[
NavigationItem(title="Blog Posts", icon=Icons.ARTICLE, link="admin:blog_post_changelist"),
NavigationItem(title="Comments", icon=Icons.COMMENT, link="admin:blog_comment_changelist"),
],
),
NavigationSection(
title="E-Commerce",
separator=True,
items=[
NavigationItem(title="Products", icon=Icons.INVENTORY, link="admin:shop_product_changelist"),
NavigationItem(title="Orders", icon=Icons.SHOPPING_CART, link="admin:shop_order_changelist"),
],
),
NavigationSection(
title="User Management",
separator=True,
items=[
NavigationItem(title="Users", icon=Icons.PEOPLE, link="admin:auth_user_changelist"),
NavigationItem(title="Profiles", icon=Icons.ACCOUNT_CIRCLE, link="admin:profiles_profile_changelist"),
],
),
],
)Navigation Options
Separators
Add visual separators between sections:
NavigationSection(
title="Section Name",
separator=True, # Adds separator above section
items=[...],
)Icons
Use Icons constants from django_cfg:
from django_cfg import Icons, NavigationItem
NavigationItem(title="Dashboard", icon=Icons.DASHBOARD, link="admin:index")Common icons:
Icons.DASHBOARD- Dashboard/overviewIcons.ARTICLE- Blog posts/contentIcons.INVENTORY- Products/itemsIcons.SHOPPING_CART- Orders/cartIcons.PEOPLE- UsersIcons.SETTINGS- SettingsIcons.ANALYTICS- Analytics/reports
Collapsible Sections
Create expandable sections:
NavigationSection(
title="Reports",
collapsible=True,
items=[
NavigationItem(title="Sales Report", link="admin:reports_sales_changelist"),
NavigationItem(title="User Report", link="admin:reports_users_changelist"),
],
)Model Admin Customization
Basic Admin Registration
# apps/blog/admin.py
from django.contrib import admin
from unfold.admin import ModelAdmin
from .models import Post, Comment
@admin.register(Post)
class PostAdmin(ModelAdmin):
list_display = ['title', 'author', 'status', 'created_at']
list_filter = ['status', 'created_at']
search_fields = ['title', 'content']
date_hierarchy = 'created_at'
fieldsets = (
('Content', {
'fields': ('title', 'content', 'status')
}),
('Metadata', {
'fields': ('author', 'created_at', 'updated_at'),
'classes': ('collapse',)
}),
)
readonly_fields = ['created_at', 'updated_at']List Display Customization
@admin.register(Order)
class OrderAdmin(ModelAdmin):
list_display = [
'id',
'user_email',
'total_amount',
'status_badge',
'created_at'
]
def user_email(self, obj):
return obj.user.email
user_email.short_description = 'Customer'
def total_amount(self, obj):
return f"${obj.total:,.2f}"
total_amount.short_description = 'Total'
def status_badge(self, obj):
colors = {
'pending': 'warning',
'processing': 'info',
'completed': 'success',
'cancelled': 'danger'
}
return f'<span class="badge badge-{colors[obj.status]}">{obj.status}</span>'
status_badge.short_description = 'Status'
status_badge.allow_tags = TrueInline Editing
class OrderItemInline(admin.TabularInline):
model = OrderItem
extra = 1
fields = ['product', 'quantity', 'price']
@admin.register(Order)
class OrderAdmin(ModelAdmin):
inlines = [OrderItemInline]Actions
Add custom bulk actions:
@admin.register(Post)
class PostAdmin(ModelAdmin):
actions = ['publish_posts', 'unpublish_posts']
def publish_posts(self, request, queryset):
updated = queryset.update(status='published')
self.message_user(
request,
f'{updated} post(s) published successfully.'
)
publish_posts.short_description = 'Publish selected posts'
def unpublish_posts(self, request, queryset):
updated = queryset.update(status='draft')
self.message_user(
request,
f'{updated} post(s) unpublished.'
)
unpublish_posts.short_description = 'Unpublish selected posts'Advanced Features
Tabbed Interface
Organize fields in tabs:
@admin.register(Product)
class ProductAdmin(ModelAdmin):
fieldsets = (
('Basic Information', {
'fields': ('name', 'description', 'category')
}),
('Pricing', {
'fields': ('price', 'discount_price', 'tax_rate')
}),
('Inventory', {
'fields': ('stock', 'reorder_level', 'supplier')
}),
('Media', {
'fields': ('image', 'gallery')
}),
)Filters
Add sidebar filters:
@admin.register(Post)
class PostAdmin(ModelAdmin):
list_filter = [
'status',
'created_at',
('author', admin.RelatedFieldListFilter),
]Search
Configure search functionality:
@admin.register(Product)
class ProductAdmin(ModelAdmin):
search_fields = [
'name',
'description',
'sku',
'category__name'
]Autocomplete
Enable autocomplete for foreign keys:
@admin.register(Post)
class PostAdmin(ModelAdmin):
autocomplete_fields = ['author', 'category']
@admin.register(User)
class UserAdmin(ModelAdmin):
search_fields = ['email', 'first_name', 'last_name']Sidebar Configuration
Sidebar Settings
from django_cfg import UnfoldConfig, UnfoldSidebar
UnfoldConfig(
sidebar=UnfoldSidebar(
show_search=True, # Enable search box
show_all_applications=False, # Hide ungrouped apps
),
)Search Box
Enable global search in sidebar:
sidebar=UnfoldSidebar(
show_search=True,
)Users can search for:
- Model names
- Navigation items
- Recent actions
Accessing the Admin
Login
Visit http://127.0.0.1:8000/admin/
Creating Superuser
Create additional admin users:
# Interactive prompt
python manage.py createsuperuser
# With credentials
python manage.py createsuperuser \
--email [email protected] \
--noinputPermissions
Control admin access:
@admin.register(Post)
class PostAdmin(ModelAdmin):
def has_delete_permission(self, request, obj=None):
# Only superusers can delete
return request.user.is_superuser
def get_queryset(self, request):
# Users only see their own posts
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)Best Practices
1. Organize Navigation Logically
Group related items together using NavigationSection:
# ✅ Good: Logical grouping
navigation=[
NavigationSection(title="Content", separator=True, items=[...]),
NavigationSection(title="E-Commerce", separator=True, items=[...]),
NavigationSection(title="Users", separator=True, items=[...]),
]
# ❌ Bad: Random order or raw dicts
navigation=[
{"title": "Orders", ...}, # Wrong: use NavigationSection objects
]2. Use Meaningful Dashboard Metrics
Show actionable business metrics:
# ✅ Good: Actionable metrics
{
"title": "Orders Today",
"value": "23",
"description": "+12% vs yesterday"
}
# ❌ Bad: Meaningless numbers
{
"title": "Database Records",
"value": "1,234,567"
}3. Customize List Displays
Make lists informative and scannable:
# ✅ Good: Relevant information
list_display = ['title', 'author', 'status', 'views', 'created_at']
# ❌ Bad: Too much or too little
list_display = ['id']4. Add Helpful Actions
Provide bulk operations:
# ✅ Good: Common operations
actions = ['publish_posts', 'archive_posts', 'export_csv']
# ❌ Bad: Only default delete actionRelated Topics
- Configuration - Unfold configuration details
- Authentication - User authentication setup
- Project Structure - Admin file organization
A well-designed admin interface improves productivity and user experience!