Skip to main content

Unfold Admin Module

Django-CFG includes a comprehensive Unfold admin interface integration that provides beautiful, modern admin dashboards with advanced theming, navigation, and monitoring capabilities.

Overviewโ€‹

The Django Unfold module provides:

  • Modern Admin Interface - Beautiful, responsive admin design
  • Advanced Dashboard - Customizable dashboard with widgets and statistics
  • Theme System - Complete theming with colors, fonts, and layouts
  • Navigation Management - Dynamic sidebar and navigation configuration
  • System Monitoring - Real-time system health and performance metrics
  • Callback System - Extensible callback system for custom functionality

Quick Startโ€‹

Automatic Integrationโ€‹

# config.py
from django_cfg import DjangoConfig, UnfoldConfig

class MyConfig(DjangoConfig):
# Enable Unfold admin interface
unfold: UnfoldConfig | None = UnfoldConfig(
site_title="My Admin",
site_header="My Project Administration",
)

Manual Configurationโ€‹

# settings.py
INSTALLED_APPS = [
"unfold", # Must be before django.contrib.admin
"django.contrib.admin",
# ... other apps
"django_cfg",
]

# Unfold settings
UNFOLD = {
"SITE_TITLE": "Django CFG Admin",
"SITE_HEADER": "Django CFG Administration",
"SITE_URL": "/",
"SITE_ICON": "speed",
"SITE_LOGO": {
"light": "/static/logo-light.svg",
"dark": "/static/logo-dark.svg",
},
"SITE_SYMBOL": "speed",
"SHOW_HISTORY": True,
"SHOW_VIEW_ON_SITE": True,
"ENVIRONMENT": "django_cfg.core.environment.get_environment_name",
"LOGIN": {
"image": "/static/admin-login.jpg",
"redirect_after": "/admin/",
},
"STYLES": [
lambda request: "/static/css/custom-admin.css",
],
"SCRIPTS": [
lambda request: "/static/js/custom-admin.js",
],
}

Theme Systemโ€‹

Built-in Themesโ€‹

from django_cfg.modules.django_unfold import UnfoldTheme, get_unfold_colors

# Available themes
class MyConfig(DjangoConfig):
unfold_theme: str = "blue" # blue, green, purple, red, orange, yellow
unfold_mode: str = "auto" # light, dark, auto

# Custom colors
unfold_primary_color: str = "#3b82f6"
unfold_secondary_color: str = "#64748b"
unfold_success_color: str = "#10b981"
unfold_warning_color: str = "#f59e0b"
unfold_error_color: str = "#ef4444"

# Get theme colors programmatically
colors = get_unfold_colors("blue")
print(colors.primary) # #3b82f6
print(colors.secondary) # #64748b

Custom Theme Configurationโ€‹

from django_cfg.modules.django_unfold.models import UnfoldThemeConfig

class CustomThemeConfig(UnfoldThemeConfig):
"""Custom theme configuration"""

primary_color: str = "#6366f1"
secondary_color: str = "#8b5cf6"
accent_color: str = "#06b6d4"

# Typography
font_family: str = "Inter, system-ui, sans-serif"
font_size_base: str = "14px"

# Layout
sidebar_width: str = "280px"
header_height: str = "64px"

# Animations
transition_duration: str = "200ms"
border_radius: str = "8px"

# Apply custom theme
class MyConfig(DjangoConfig):
unfold_theme_config: CustomThemeConfig = CustomThemeConfig()

๐Ÿงญ Navigation Systemโ€‹

Dynamic Navigationโ€‹

from django_cfg.modules.django_unfold.models import NavigationItem, NavigationSection

class MyConfig(DjangoConfig):
unfold_navigation: list = [
NavigationSection(
title="Content Management",
items=[
NavigationItem(
title="Posts",
icon="article",
link="/admin/blog/post/",
badge="new"
),
NavigationItem(
title="Categories",
icon="category",
link="/admin/blog/category/"
),
]
),
NavigationSection(
title="User Management",
items=[
NavigationItem(
title="Users",
icon="people",
link="/admin/auth/user/",
permission="auth.view_user"
),
NavigationItem(
title="Groups",
icon="group",
link="/admin/auth/group/",
permission="auth.view_group"
),
]
),
NavigationSection(
title="Django CFG",
items=[
NavigationItem(
title="System Monitor",
icon="monitor_heart",
link="/admin/django_cfg/system/",
permission="is_staff"
),
NavigationItem(
title="Configuration",
icon="settings",
link="/admin/constance/config/",
permission="is_superuser"
),
]
)
]

Conditional Navigationโ€‹

def get_navigation_items(request):
"""Dynamic navigation based on user permissions"""
items = []

# Always visible items
items.append(NavigationItem(
title="Dashboard",
icon="dashboard",
link="/admin/"
))

# User management (staff only)
if request.user.is_staff:
items.append(NavigationSection(
title="User Management",
items=[
NavigationItem(
title="Users",
icon="people",
link="/admin/auth/user/"
),
NavigationItem(
title="Activity Log",
icon="history",
link="/admin/accounts/activity/"
),
]
))

# System administration (superuser only)
if request.user.is_superuser:
items.append(NavigationSection(
title="System",
items=[
NavigationItem(
title="Configuration",
icon="settings",
link="/admin/constance/config/"
),
NavigationItem(
title="System Monitor",
icon="monitor_heart",
link="/admin/system/monitor/"
),
]
))

return items

# Use in settings
UNFOLD = {
"SIDEBAR": {
"navigation": "myapp.navigation.get_navigation_items",
}
}

System Monitoringโ€‹

System Monitorโ€‹

from django_cfg.modules.django_unfold import SystemMonitor, get_system_monitor

# Get system monitor
monitor = get_system_monitor()

# Get system metrics
metrics = monitor.get_system_metrics()
print(metrics)
# {
# 'cpu_usage': 45.2,
# 'memory_usage': 62.8,
# 'disk_usage': 78.1,
# 'load_average': 1.23,
# 'uptime': '2 days, 14:32:15',
# 'processes': 156
# }

# Get Django metrics
django_metrics = monitor.get_django_metrics()
print(django_metrics)
# {
# 'active_sessions': 23,
# 'total_users': 1247,
# 'database_connections': 8,
# 'cache_hit_rate': 94.2,
# 'response_time_avg': 120.5
# }

Custom Monitoring Widgetsโ€‹

# admin.py
from django.contrib import admin
from django_cfg.modules.django_unfold import get_system_monitor

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
def changelist_view(self, request, extra_context=None):
"""Add system monitoring to changelist"""
extra_context = extra_context or {}

monitor = get_system_monitor()
extra_context.update({
'system_metrics': monitor.get_system_metrics(),
'django_metrics': monitor.get_django_metrics(),
'custom_metrics': self.get_custom_metrics()
})

return super().changelist_view(request, extra_context)

def get_custom_metrics(self):
"""Get model-specific metrics"""
return {
'total_records': MyModel.objects.count(),
'active_records': MyModel.objects.filter(is_active=True).count(),
'recent_records': MyModel.objects.filter(
created_at__gte=timezone.now() - timedelta(days=7)
).count()
}

Advanced Configurationโ€‹

Complete Unfold Configurationโ€‹

# settings.py
UNFOLD = {
# Site configuration
"SITE_TITLE": "Django CFG Admin",
"SITE_HEADER": "Django CFG Administration",
"SITE_URL": "/",
"SITE_ICON": {
"light": "/static/icon-light.svg",
"dark": "/static/icon-dark.svg",
},
"SITE_LOGO": {
"light": "/static/logo-light.svg",
"dark": "/static/logo-dark.svg",
},
"SITE_SYMBOL": "speed",

# Environment
"ENVIRONMENT": "django_cfg.core.environment.get_environment_name",
"SHOW_HISTORY": True,
"SHOW_VIEW_ON_SITE": True,

# Theme
"THEME": "auto", # light, dark, auto
"COLORS": {
"primary": {
"50": "#eff6ff",
"100": "#dbeafe",
"200": "#bfdbfe",
"300": "#93c5fd",
"400": "#60a5fa",
"500": "#3b82f6",
"600": "#2563eb",
"700": "#1d4ed8",
"800": "#1e40af",
"900": "#1e3a8a",
}
},

# Sidebar
"SIDEBAR": {
"show_search": True,
"show_all_applications": False,
"navigation": [
{
"title": "Navigation",
"separator": True,
"items": [
{
"title": "Dashboard",
"icon": "dashboard",
"link": "/admin/",
},
{
"title": "Users",
"icon": "people",
"link": "/admin/auth/user/",
"permission": lambda request: request.user.is_staff,
},
]
}
]
},

# Tabs
"TABS": [
{
"models": ["auth.user"],
"items": [
{
"title": "Profile",
"link": "/admin/auth/user/{}/change/",
},
{
"title": "Activity",
"link": "/admin/accounts/activity/?user__id__exact={}",
},
]
}
],

# Login page
"LOGIN": {
"image": "/static/admin-login.jpg",
"redirect_after": "/admin/",
},

# Custom CSS/JS
"STYLES": [
lambda request: "/static/css/custom-admin.css",
],
"SCRIPTS": [
lambda request: "/static/js/custom-admin.js",
],
}

Integration with Django-CFG Appsโ€‹

# Automatic integration with Django-CFG apps
from django_cfg import DjangoConfig, UnfoldConfig

class MyConfig(DjangoConfig):
unfold: UnfoldConfig | None = UnfoldConfig()
enable_accounts: bool = True
enable_support: bool = True
enable_newsletter: bool = True

# Unfold will automatically configure navigation for enabled apps
unfold_auto_navigation: bool = True

# Custom dashboard widgets for each app
unfold_dashboard_widgets: dict = {
'accounts': ['user_stats', 'activity_chart'],
'support': ['ticket_stats', 'response_time'],
'newsletter': ['subscriber_stats', 'campaign_performance']
}

๐Ÿงช Testing Unfold Integrationโ€‹

Unit Testsโ€‹

from django.test import TestCase, Client
from django.contrib.auth import get_user_model
from rest_framework.test import APIClient

User = get_user_model()

class UnfoldIntegrationTest(TestCase):
def setUp(self):
self.client = Client()
self.api_client = APIClient()
self.user = User.objects.create_superuser(
username='admin',
email='admin@example.com',
password='password'
)
self.api_client.force_authenticate(user=self.user)

def test_dashboard_api(self):
"""Test dashboard API endpoints"""
# Test statistics endpoint
response = self.api_client.get('/cfg/dashboard/api/statistics/')
self.assertEqual(response.status_code, 200)
self.assertIn('user_statistics', response.data)

# Test health endpoint
response = self.api_client.get('/cfg/dashboard/api/health/')
self.assertEqual(response.status_code, 200)
self.assertIn('database', response.data)

def test_admin_access(self):
"""Test admin interface access"""
self.client.force_login(self.user)

# Test admin index loads
response = self.client.get('/admin/')
self.assertEqual(response.status_code, 200)

# Test Next.js dashboard iframe loads
self.assertContains(response, 'nextjs-dashboard-iframe')

def test_navigation_generation(self):
"""Test navigation generation"""
request = self.factory.get('/admin/')
request.user = self.user

from django_cfg.modules.django_unfold.callbacks import get_navigation_items
navigation = get_navigation_items(request)

self.assertIsInstance(navigation, list)
self.assertTrue(len(navigation) > 0)

What's Newโ€‹

Next.js Dashboard (Latest)โ€‹

Django-CFG now includes a modern Next.js-based dashboard with real-time capabilities:

  • โœ… Next.js Dashboard - Modern React-based admin dashboard served via iframe
  • โœ… REST API Backend - Complete API at /cfg/dashboard/api/ for all dashboard data
  • โœ… Type-Safe - Full TypeScript + Pydantic type safety
  • โœ… Real-Time - WebSocket support via Centrifugo integration
  • โœ… Auto Navigation - Automatically adapts to enabled Django-CFG modules

Learn more: What's New in Unfold

The Unfold Admin module provides a beautiful, modern admin interface for your Django applications! ๐ŸŽจ

TAGS: unfold, admin-interface, dashboard, theming, navigation, monitoring, widgets DEPENDS_ON: [configuration, admin, theming, widgets] USED_BY: [all-apps, administration, monitoring]