Skip to main content

Customizable data dashboards for Django Admin with KPI cards, charts, tables, and filters

Project description

Django Admin Dashboards

Python 版本 Django 版本 许可证 文档 Gitee 仓库 Vibe Coding: opencode+deepseek-reasoner

Django Admin Dashboards 是一个强大的 Django 应用程序,它将默认的 Django Admin 界面转换为完全可定制的数据看板系统。用包含卡片、图表、表格和过滤器的数据看板替换静态的管理页面。

本项目使用AI辅助编程工具(opencode + deepseek-reasoner)自动生成和维护

✨ 主要特性

  • 交互式数据看板布局:响应式网格布局(12列系统)支持灵活的行配置
  • 多种组件类型
    • Cards(支持图标和单值/多值显示)
    • Charts(折线图、柱状图、饼图等)使用 Chart.js
    • Data Tables 支持排序和分页
    • Filter Components 用于数据过滤
  • 深色模式支持:完全兼容 Django Admin 的深色模式
  • 全屏模式:专用的全屏查看体验,支持 URL 参数控制
  • 可定制导航:与 django-admin-global-sidebar 集成
  • 多语言支持:内置中文翻译,可扩展支持其他语言
  • 灵活配置:通过 URL 参数控制深色模式、全屏模式和布局选项

📦 安装

pip install django-admin-dashboards

或从源代码安装:

git clone https://gitee.com/rRR0VrFP/django-admin-dashboards.git
cd django-admin-dashboards
pip install -e .

🚀 快速开始

  1. 在 Django 设置中添加 INSTALLED_APPS
INSTALLED_APPS = [
    "django_admin_dashboards",  # 必须在 django.contrib.admin 之前
    "django_static_remixicon",  # 图标必需
    "django.contrib.admin",
    # ... 其他应用
]
  1. 在 settings.py 中配置数据看板映射
DJANGO_ADMIN_DASHBOARDS = {
    "admin:index": "django_admin_dashboards.contrib.auth.dashboard.AuthAppDashboard",
    "admin:app_list": {
        "auth": "django_admin_dashboards.contrib.auth.dashboard.AuthAppDashboard",
    },
}

📊 创建自定义数据看板

基本数据看板示例

通过扩展 Dashboard 基类创建自定义数据看板:

# myapp/dashboards.py
from django_admin_dashboards.base import Dashboard, CardComponent, ChartComponent, Layout, TableComponent
from django.utils.translation import gettext_lazy as _
from django.db.models import Count
from datetime import datetime, timedelta
from django.utils import timezone

class MyCustomDashboard(Dashboard):
    title = _("My Dashboard")
    show_dashboard_title = True
    show_admin_title = False
    hide_others_in_fullscreen = True  # Enable fullscreen hide feature

    def get_layout(self):
        layout = Layout(columns=12)
        
        # 添加卡片
        layout.add_row([
            (CardComponent(
                title="Total Users",
                value=150,
                change="+12%",
                trend="up",
                color="primary",
                icon_class="ri-user-line"
            ), 4),
            (CardComponent(
                title="Active Sessions",
                value=42,
                change="-3%",
                trend="down",
                color="success",
                icon_class="ri-user-heart-line"
            ), 4),
            (CardComponent(
                title="Revenue",
                value="$12,450",
                change="+24%",
                trend="up",
                color="warning",
                icon_class="ri-money-dollar-circle-line"
            ), 4),
        ], height="auto")
        
        # Add chart
        layout.add_row([
            (ChartComponent(
                title="User Registration Trends",
                chart_type="line",
                data={
                    "labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
                    "datasets": [{
                        "label": "New Users",
                        "data": [65, 59, 80, 81, 56, 55],
                        "borderColor": "rgb(75, 192, 192)",
                    }]
                },
                options={
                    "responsive": True,
                    "plugins": {"legend": {"position": "top"}},
                }
            ), 12)
        ], height="400px")
        
        # Add table
        layout.add_row([
            (TableComponent(
                title="Recent Activity",
                columns=["User", "Action", "Date", "Status"],
                data=[
                    ["john_doe", "Login", "2024-01-15", "Success"],
                    ["jane_smith", "Profile Update", "2024-01-14", "Success"],
                    ["bob_johnson", "Password Reset", "2024-01-13", "Pending"],
                ]
            ), 12)
        ], height="auto")
        
        return layout
    
    def get_kpi_cards(self):
        """重写此方法以提供动态的指标数据"""
        from django.contrib.auth.models import User
        from django.db.models import Q
        
        total_users = User.objects.count()
        active_users = User.objects.filter(is_active=True).count()
        recent_users = User.objects.filter(
            date_joined__gte=timezone.now() - timedelta(days=30)
        ).count()
        
        return [
            CardComponent(
                title="User Status",
                values=[active_users, total_users - active_users, total_users],
                value_labels=["Active", "Inactive", "Total"],
                color="primary",
                icon_class="ri-user-2-line"
            ),
            # ... more cards
        ]

多值卡片

在单个卡片中显示多个值:

CardComponent(
    title="User Status",
    values=[85, 15, 100],  # Active, Inactive, Total
    value_labels=["Active", "Inactive", "Total"],
    color="primary",
    icon_class="ri-user-2-line"
)

🧩 组件参考

CardComponent

显示指标数据,支持趋势指示器和图标。

CardComponent(
    title="Card Title",
    value=42,  # Main value (optional if using values)
    change="+12%",  # Percentage change
    trend="up",  # "up", "down", or "neutral"
    color="primary",  # "primary", "success", "warning", "danger", "info", "secondary"
    icon_class="ri-bar-chart-2-line",  # remixicon class
    
    # Multi-value display (alternative to single value)
    values=[10, 20, 30],
    value_labels=["Label1", "Label2", "Label3"],
)

可用颜色: primary, success, warning, danger, info, secondary

ChartComponent

使用 Chart.js 的交互式图表。

ChartComponent(
    title="Chart Title",
    chart_type="line",  # "line", "bar", "pie", "doughnut", "radar", "polarArea"
    data={
        "labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
        "datasets": [
            {
                "label": "Dataset 1",
                "data": [65, 59, 80, 81, 56, 55],
                "borderColor": "rgb(75, 192, 192)",
                "backgroundColor": "rgba(75, 192, 192, 0.1)",
                "fill": True,
            }
        ]
    },
    options={
        "responsive": True,
        "maintainAspectRatio": False,
        "plugins": {
            "legend": {"position": "top"},
        },
        "scales": {
            "y": {"beginAtZero": True}
        }
    },
    height=400,  # Height in pixels
)

TableComponent

用于显示表格数据的表格组件。

TableComponent(
    title="Table Title",
    columns=["Column 1", "Column 2", "Column 3"],  # Column headers
    data=[  # Row data
        ["Row 1 Col 1", "Row 1 Col 2", "Row 1 Col 3"],
        ["Row 2 Col 1", "Row 2 Col 2", "Row 2 Col 3"],
        ["Row 3 Col 1", "Row 3 Col 2", "Row 3 Col 3"],
    ],
)

FilterComponent

用于数据看板数据的交互式过滤器,提供现代化触发按钮+下拉面板界面,支持 Select2 搜索和多选功能。

FilterComponent(
    title="Filters",
    filters=[
        {
            "name": "date_range",
            "label": "Date Range",
            "type": "date_range",
            "options": [
                {"value": "today", "label": "Today"},
                {"value": "yesterday", "label": "Yesterday"},
                {"value": "last_7_days", "label": "Last 7 Days"},
                {"value": "last_30_days", "label": "Last 30 Days"},
                {"value": "custom", "label": "Custom Range"},
            ],
            "default": "last_30_days",
        },
        {
            "name": "status",
            "label": "Status",
            "type": "multi_select",  # 支持多选
            "options": [
                {"value": "active", "label": "Active"},
                {"value": "pending", "label": "Pending"},
                {"value": "completed", "label": "Completed"},
                {"value": "cancelled", "label": "Cancelled"},
            ],
            "default": ["active", "pending"],  # 多选默认值可以是数组
        },
        {
            "name": "price_range",
            "label": "Price Range",
            "type": "number_range",  # 数值范围(最小值和最大值)
            "default_min": 0,
            "default_max": 1000,
        },
        {
            "name": "category",
            "label": "Category",
            "type": "select",  # 单选下拉框,支持 Select2 搜索
            "options": [
                {"value": "all", "label": "All Categories"},
                {"value": "electronics", "label": "Electronics"},
                {"value": "clothing", "label": "Clothing"},
                {"value": "books", "label": "Books"},
            ],
            "default": "all",
        },
        {
            "name": "search",
            "label": "Search",
            "type": "text",  # 文本搜索
            "placeholder": "Enter keywords...",
        },
    ],
)

🛠️ 过滤器管理器

Django Admin Dashboards 提供 FiltersManager 抽象基类,用于简化业务过滤器的定义和共享。通过使用过滤器管理器,您可以在多个数据看板和数据源之间共享过滤器配置和过滤逻辑,避免代码重复。

FiltersManager 基类

FiltersManager 是一个抽象基类,提供以下核心功能:

  • 统一的过滤器配置管理:通过 get_filters_config() 方法定义过滤器配置
  • 过滤器应用逻辑:通过 apply_filters() 方法将过滤器应用到查询集
  • 便捷的过滤器创建方法:提供 create_select_filter()create_multi_select_filter() 等静态方法
  • FilterHelper 集成:自动处理请求参数和过滤器状态
from django_admin_dashboards.base import FiltersManager

class MyFiltersManager(FiltersManager):
    """自定义过滤器管理器"""
    
    @classmethod
    def get_filters_config(cls):
        """返回过滤器配置列表"""
        return [
            cls.create_select_filter(
                name="category",
                label="产品分类",
                options=[
                    {"value": "all", "label": "全部分类"},
                    {"value": "electronics", "label": "电子产品"},
                    {"value": "clothing", "label": "服装服饰"},
                ],
                default="all",
            ),
            cls.create_date_range_filter(
                name="date_range",
                label="日期范围",
                default="last_30_days",
            ),
        ]
    
    def apply_filters(self, queryset, filter_helper=None):
        """将过滤器应用到查询集"""
        if filter_helper is None:
            filter_helper = self.get_filter_helper()
        
        if filter_helper is None:
            return queryset
        
        # 应用分类过滤
        category = filter_helper.get_value("category", "all")
        if category != "all":
            queryset = queryset.filter(category=category)
        
        # 应用日期范围过滤
        start_date, end_date = filter_helper.get_date_range("date_range")
        if start_date and end_date:
            queryset = queryset.filter(
                created_at__gte=start_date,
                created_at__lte=end_date
            )
        
        return queryset

在 Dashboard 中集成过滤器管理器

在自定义数据看板中,通过设置 filters_manager_class 属性来集成过滤器管理器:

from django_admin_dashboards.base import Dashboard
from .filters import MyFiltersManager

class MyDashboard(Dashboard):
    title = "我的数据看板"
    filters_manager_class = MyFiltersManager  # 集成过滤器管理器
    
    def get_layout(self):
        # 布局定义...
        pass
    
    def get_context_data(self, request):
        context = super().get_context_data(request)
        # 可以通过 self.get_filters_manager(request) 获取过滤器管理器实例
        filters_manager = self.get_filters_manager(request)
        if filters_manager:
            # 使用过滤器管理器...
            pass
        return context

在 DataSource 中集成过滤器管理器

数据源也可以通过 filters_manager_class 属性集成过滤器管理器,实现过滤器配置和逻辑的共享:

from django_admin_dashboards.base import SecurityCheckedDataSource

@DataSource.register
class MyDataSource(SecurityCheckedDataSource):
    source_id = "my_data_source"
    description = "我的数据源"
    permission_required = "app.view_model"
    filters_manager_class = MyFiltersManager  # 集成过滤器管理器
    
    def _fetch_data(self, request):
        # 获取过滤器管理器实例
        filters_manager = self.get_filters_manager(request)
        
        # 获取基础查询集
        queryset = MyModel.objects.all()
        
        # 应用过滤器
        if filters_manager:
            queryset = filters_manager.apply_filters(queryset)
        
        # 处理数据并返回
        return queryset.count()

🔌 数据源系统

Django Admin Dashboards 提供安全的数据源系统,用于异步数据加载。所有数据源都必须预定义并注册,确保安全性。

SecurityCheckedDataSource 基类

from django_admin_dashboards.base import SecurityCheckedDataSource

@DataSource.register
class MyDataSource(SecurityCheckedDataSource):
    source_id = "my_data_source"
    description = "我的数据源描述"
    permission_required = "app.view_model"
    
    def _fetch_data(self, request):
        # 实现数据获取逻辑
        return {"data": "example"}

组件数据源支持

组件可以通过 data_source 参数使用数据源:

# 卡片组件使用数据源
CardComponent(
    title="用户统计",
    data_source=UserCountDataSource(count_active_only=True)
)

# 图表组件使用数据源 - 需要实际数据
ChartComponent(
    title="用户活动趋势",
    chart_type="line",
    # 图表数据源需要返回图表.js兼容的数据结构
    # 这里只是示例,实际需要实现返回图表数据的数据源
    data_source=None  # 替换为实际的图表数据源
)

# 表格组件使用数据源
TableComponent(
    title="用户角色分布",
    columns=["角色", "数量"],
    # 使用 UserRoleDistributionDataSource,但需要适配表格格式
    # 实际使用中需要实现返回表格数据的数据源
    data_source=None  # 替换为实际的表格数据源
)

# 更多实际示例
CardComponent(
    title="最近活跃用户",
    data_source=RecentUserActivityDataSource(days=7, active_only=True)
)

CardComponent(
    title="权限统计",
    data_source=PermissionCountDataSource()
)

安全要求

  1. 预定义与注册:所有数据源必须预定义并注册
  2. 权限检查:数据源实现中必须包含权限检查
  3. 唯一标识符:每个数据源必须有唯一的 source_id
  4. 安全反序列化:使用 DataSource.create_from_json() 确保安全

🎛️ 数据看板配置选项

类属性

Option Type Default Description
title string None 数据看板标题,显示在页眉中
show_dashboard_title bool True 显示/隐藏数据看板标题
show_admin_title bool False 显示/隐藏默认的 Django admin 标题
hide_others_in_fullscreen bool False 启用功能:在全屏模式下隐藏周围元素
force_hide_others bool False 启用功能:始终隐藏周围元素
template_name string "admin/dashboard.html" 用于数据看板渲染的自定义模板

URL 参数控制

数据看板行为可以通过 URL 参数控制:

Parameter Values Description
_dark_mode_on true, false, auto 控制深色模式:true=强制深色,false=强制浅色,auto=跟随 Django admin 设置
_hide_others_in_fullscreen true, false 在全屏模式下隐藏周围元素(需要数据看板支持此功能)
_force_hide_others true, false 始终隐藏周围元素,无论是否全屏模式

示例URL:

  • /admin/?_dark_mode_on=true - 强制深色模式
  • /admin/?_dark_mode_on=false - 强制浅色模式
  • /admin/?_dark_mode_on=auto - 跟随 Django admin 主题
  • /admin/?_hide_others_in_fullscreen=true - 全屏模式下隐藏周围元素
  • /admin/?_force_hide_others=true - 始终隐藏周围元素

🌙 深色模式支持

数据看板完全支持 Django Admin 的深色模式系统,并提供基于 URL 的额外控制:

  • 自动检测:跟随 Django Admin 的主题设置
  • URL 覆盖:使用 ?_dark_mode_on=true/false/auto 进行覆盖
  • CSS 兼容性:所有组件都有深色模式样式
  • 主题保留:在 auto 模式下,深色模式切换按钮仍然有效

🖥️ 全屏模式

数据看板可以在全屏模式下查看,有两种控制选项:

1. 全屏模式下隐藏

数据看板元素仅在浏览器全屏模式下隐藏周围的 admin UI。 要求:在数据看板类中设置 hide_others_in_fullscreen = True + URL 参数 ?_hide_others_in_fullscreen=true

2. 强制隐藏其他元素

始终隐藏周围元素,无论是否全屏模式。 要求:在数据看板类中设置 force_hide_others = True + URL 参数 ?_force_hide_others=true

📄 许可证

MIT 许可证 - 详情请见 LICENSE 文件。

📝 版本历史

v0.1.1 (2026-05-08)

  • 修复打包错误:packages 配置现在包含所有子包(contrib.*managementtemplatetagsmigrations

v0.1.0 (2026-04-11)

  • 初始版本
  • 数据看板系统,包含卡片、图表、表格和过滤器
  • 支持深色模式,可通过 URL 参数控制
  • 全屏模式,支持隐藏选项
  • 响应式网格布局系统
  • 内置 AuthAppDashboard 示例

🤝 贡献指南

欢迎贡献!请随时提交 Pull Request。

  1. Fork 仓库
  2. 创建功能分支(git checkout -b feature/amazing-feature
  3. 提交更改(git commit -m 'Add amazing feature'
  4. 推送到分支(git push origin feature/amazing-feature
  5. 打开 Pull Request

📧 支持

如有问题、疑问或功能请求,请在 Gitee 仓库中提交 issue。

您也可以通过 rrr0vrfp@qq.com 联系维护者。


Django Admin Dashboards - 将您的 Django Admin 转变为强大的分析数据看板!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_admin_dashboards-0.1.1.tar.gz (116.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_admin_dashboards-0.1.1-py3-none-any.whl (118.4 kB view details)

Uploaded Python 3

File details

Details for the file django_admin_dashboards-0.1.1.tar.gz.

File metadata

  • Download URL: django_admin_dashboards-0.1.1.tar.gz
  • Upload date:
  • Size: 116.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.12

File hashes

Hashes for django_admin_dashboards-0.1.1.tar.gz
Algorithm Hash digest
SHA256 30aca9f1aad4b2049d5984fc12a55723406514381f0e31e072359e3786b92302
MD5 11275854b7f2d9420926a36f1b77da77
BLAKE2b-256 a4a6213993c7c4265a16432a0e5d99f7ba8e9b3f61113cfd9511b888664a9416

See more details on using hashes here.

File details

Details for the file django_admin_dashboards-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for django_admin_dashboards-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 54c8bb5cafb3ce49bf8e98e9936d4bebf126b91aec433fa4d0f279737947eac0
MD5 ae31b010e7734cdba99082948f4658ba
BLAKE2b-256 50b0fb74ed600923ade1e78d4703ad111f00c0e9a6febe8927d1ba8a91123629

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page