跳转至

Components API 参考

组件是 Django Admin Dashboards 中数据看板的构建块。本参考涵盖所有组件类、其属性、方法和使用模式。

目录

概述

什么是组件?

组件是表示数据看板上视觉元素的Python类:

  1. 自包含: 每个组件管理自己的数据和渲染
  2. 可配置: 属性控制外观和行为
  3. 基于模板: HTML模板定义视觉呈现
  4. 上下文感知: 能适应请求上下文和用户

组件类型

组件 描述 使用场景
CardComponent 显示带有图标、值和趋势的指标 指标、统计、关键指标
ChartComponent 使用图表.js进行数据可视化 趋势、比较、分布
TableComponent 表格数据展示 列表、网格、详细数据
FilterComponent 交互式过滤控件 数据过滤、参数选择
自定义组件 用户定义的组件 专用可视化

导入路径

    from django_admin_dashboards.base import (
        Component,
        CardComponent,
        ChartComponent,
        TableComponent,
        FilterComponent
    )

组件基类

Component

    class Component:
        """基础组件类"""

        component_type = None
        template_name = None

        def __init__(self, **kwargs):
            """使用关键字参数初始化组件"""

        def get_context_data(self, request):
            """获取组件渲染的上下文数据"""

        def render(self, request):
            """将组件渲染为HTML"""

属性

属性 类型 默认值 描述
component_type str None 组件类型标识符
template_name str None 渲染模板路径

方法

__init__(**kwargs)

参数:

  • **kwargs: 组件属性作为关键字参数

描述:

初始化组件实例。所有关键字参数都设置为实例属性。

使用:

    component = Component(title="My Component", value=100)
    print(component.title)  # "My Component"

    print(component.value)  # 100

get_context_data(request)

参数:

  • request (Django.http.HttpRequest): 当前HTTP请求

返回:

dict - 模板上下文字典

描述:

准备模板渲染的上下文数据。基类实现返回最小上下文。

默认上下文:

    {
        "component": self,
        "component_type": self.component_type,
    }

重写示例:

    def get_context_data(self, request):
        context = super().get_context_data(request)
        context["custom_data"] = self.calculate_data()
        context["user"] = request.user
        return context

render(request)

参数:

  • request (Django.http.HttpRequest): 当前HTTP请求

返回: str - HTML字符串(基础实现)

描述:

将组件渲染为HTML。实际上,组件通过Django模板渲染。

注意: 仅在特殊情况下重写;通常使用模板渲染。

卡片组件

概述

显示关键绩效指标 (KPIs),支持多值、趋势和图标。

    class CardComponent(Component):
        """Card component for displaying metrics"""

        component_type = "card"
        template_name = "admin/components/card.html"

        def __init__(
            self,
            title,
            value=None,
            change=None,
            trend=None,
            color="primary",
            icon_class=None,
            values=None,
            value_labels=None,
            **kwargs
        ):
            # ... initialization

构造函数参数

参数 类型 默认值 描述
title str 必需 卡片标题
value any None 主值(向后兼容)
change str None 变化指示器(例如 "+5%")
trend str None 趋势方向("up", "down", "neutral")
color str "primary" 颜色主题: "primary", "success", "warning", "danger", "info"
icon_class str "ri-bar-chart-2-line" RemixIcon CSS类
values list None 用于显示的多值
value_labels list [] 多值标签
link str None 单个值的链接URL
links list [] 多值对应的链接URL列表
**kwargs any - 额外组件属性

属性

属性 类型 描述
title str 卡片标题
value any 主值
change str 变化指示器
trend str 趋势方向
color str 颜色主题
icon_class str 图标CSS类
values list 多值
value_labels list 值标签
link str 单个值的链接URL
links list 多值对应的链接URL列表

使用 示例

基础 卡片

    card = CardComponent(
        title="Total Users",
        value=150,
        change="+5%",
        trend="up",
        color="primary",
        icon_class="ri-user-line"
    )

Multi-value 卡片

    card = CardComponent(
        title="User Status",
        values=[100, 25, 125],  # Active, Inactive, Total

        value_labels=["Active", "Inactive", "Total"],
        color="info",
        icon_class="ri-user-2-line"
    )

Status 卡片

    card = CardComponent(
        title="System Status",
        value="Online",
        change="✓",
        trend="up",
        color="success",
        icon_class="ri-server-line"
    )

warning 卡片

    card = CardComponent(
        title="Storage Usage",
        value="85%",
        change="+10%",
        trend="down",  # Down is bad for storage usage

        color="warning",
        icon_class="ri-hard-drive-line"
    )
    # 单个值带链接
    card = CardComponent(
        title="Total Users",
        value=150,
        link="/admin/auth/user/",  # 点击数字跳转到用户列表
        color="primary",
        icon_class="ri-user-line"
    )

    # 多值带链接
    card = CardComponent(
        title="User Status",
        values=[100, 25, 125],  # Active, Inactive, Total
        value_labels=["Active", "Inactive", "Total"],
        links=[
            "/admin/auth/user/?is_active__exact=1",
            "/admin/auth/user/?is_active__exact=0",
            "/admin/auth/user/"
        ],
        color="info",
        icon_class="ri-user-2-line"
    )

Template Context

卡片 components provide the following template context:

    {
        "component": self,
        "component_type": "card",
        "title": self.title,
        "value": self.value,
        "change": self.change,
        "trend": self.trend,
        "color": self.color,
        "icon_class": self.icon_class,
        "values": self.values,
        "value_labels": self.value_labels,
        "link": self.link,
        "links": self.links,
        "has_multiple_values": len(self.values) > 1,
        "value_pairs": list(zip(self.values, self.value_labels)),
    }

Color Themes

Available color themes and their CSS classes:

Color CSS Class Typical Use
primary 卡片-primary Primary metrics
success 卡片-success Positive indicators
warning 卡片-warning Caution/Warning
danger 卡片-danger Critical issues
info 卡片-info Informational
secondary 卡片-secondary Secondary metrics

Icon Classes

Use RemixIcon classes for icons:

    # User-related icons

    icon_class="ri-user-line"
    icon_class="ri-user-2-line"
    icon_class="ri-user-3-line"

    # Chart icons

    icon_class="ri-bar-chart-2-line"
    icon_class="ri-line-chart-line"
    icon_class="ri-pie-chart-2-line"

    # System icons

    icon_class="ri-server-line"
    icon_class="ri-database-2-line"
    icon_class="ri-cpu-line"

    # Business icons

    icon_class="ri-money-dollar-circle-line"
    icon_class="ri-shopping-cart-2-line"
    icon_class="ri-store-2-line"

图表组件

概述

创建 交互式 charts using 图表.js 库.

    class ChartComponent(Component):
        """Chart component using Chart.js"""

        component_type = "chart"
        template_name = "admin/components/chart.html"

        def __init__(self, title, chart_type, data, options=None, height=400, **kwargs):
            # ... initialization

构造函数参数

参数 类型 默认值 描述
title str 必需 图表标题
chart_type str 必需 图表类型: "line", "bar", "pie", "doughnut", "radar", "polarArea", "bubble", "scatter"
data dict 必需 图表.js 数据配置
options dict None 图表.js选项
height int 400 图表高度(像素)
**kwargs any - 额外组件属性

属性

属性 类型 描述
title str 图表标题
chart_type str 图表类型
data dict 图表数据
options dict 图表选项
height int 图表高度

使用 示例

Line 图表

    chart = ChartComponent(
        title="User Growth",
        chart_type="line",
        data={
            "labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
            "datasets": [{
                "label": "New Users",
                "data": [12, 19, 3, 5, 2, 3],
                "borderColor": "rgb(75, 192, 192)",
                "tension": 0.1
            }]
        },
        options={
            "responsive": True,
            "plugins": {
                "legend": {
                    "position": "top",
                },
                "title": {
                    "display": True,
                    "text": "Monthly User Growth"
                }
            }
        },
        height=400
    )

Bar 图表

    chart = ChartComponent(
        title="Monthly Sales",
        chart_type="bar",
        data={
            "labels": ["Q1", "Q2", "Q3", "Q4"],
            "datasets": [
                {
                    "label": "2023",
                    "data": [65, 59, 80, 81],
                    "backgroundColor": "rgba(255, 99, 132, 0.5)",
                },
                {
                    "label": "2024",
                    "data": [28, 48, 40, 19],
                    "backgroundColor": "rgba(54, 162, 235, 0.5)",
                }
            ]
        }
    )

Pie 图表

    chart = ChartComponent(
        title="User Distribution",
        chart_type="pie",
        data={
            "labels": ["Active", "Inactive", "Suspended"],
            "datasets": [{
                "label": "Users",
                "data": [300, 50, 100],
                "backgroundColor": [
                    "rgb(255, 99, 132)",
                    "rgb(54, 162, 235)",
                    "rgb(255, 205, 86)"
                ],
            }]
        }
    )

Template Context

图表 components provide the following template context:

    {
        "component": self,
        "component_type": "chart",
        "title": self.title,
        "chart_type": self.chart_type,
        "data_json": json.dumps(self.data),
        "options_json": json.dumps(self.options or {}),
        "chart_id": f"chart_{id(self)}",  # Unique ID for DOM element

        "height": self.height,
    }

图表类型

支持的 Chart.js 图表类型:

类型 描述 使用场景
line 折线图 时间趋势分析
bar 柱状图 类别对比
pie 饼图 整体比例
doughnut 环形图 带空洞的比例
radar 雷达图 多变量数据
polarArea 极区图 比例角度
bubble 气泡图 三维数据
scatter 散点图 变量关系

图表类型详细说明

每种图表类型有其特定的数据结构和选项配置:

1. 折线图 (line)

用于展示数据随时间或其他连续变量的变化趋势。

数据格式示例:

data = {
    "labels": ["1月", "2月", "3月", "4月", "5月", "6月"],
    "datasets": [{
        "label": "用户增长",
        "data": [12, 19, 3, 5, 2, 3],
        "borderColor": "rgb(75, 192, 192)",
        "backgroundColor": "rgba(75, 192, 192, 0.1)",
        "borderWidth": 2,
        "tension": 0.4,  # 曲线平滑度 (0=直线, 1=最平滑)
        "fill": True  # 是否填充区域
    }]
}

常用选项:

options = {
    "responsive": True,
    "plugins": {
        "legend": {"position": "top"},
        "tooltip": {"mode": "index", "intersect": False}
    },
    "scales": {
        "y": {
            "beginAtZero": True,
            "title": {"display": True, "text": "用户数"}
        },
        "x": {
            "title": {"display": True, "text": "月份"}
        }
    }
}

2. 柱状图 (bar)

用于比较不同类别的数值大小。

数据格式示例:

data = {
    "labels": ["第一季度", "第二季度", "第三季度", "第四季度"],
    "datasets": [
        {
            "label": "2023年",
            "data": [65, 59, 80, 81],
            "backgroundColor": "rgba(255, 99, 132, 0.7)",
            "borderColor": "rgb(255, 99, 132)",
            "borderWidth": 1
        },
        {
            "label": "2024年",
            "data": [28, 48, 40, 19],
            "backgroundColor": "rgba(54, 162, 235, 0.7)",
            "borderColor": "rgb(54, 162, 235)",
            "borderWidth": 1
        }
    ]
}

水平柱状图配置:

options = {
    "indexAxis": "y",  # 水平柱状图
    "responsive": True,
    "plugins": {
        "legend": {"position": "right"}
    }
}

3. 饼图 (pie) 和环形图 (doughnut)

用于展示各部分占整体的比例。

数据格式示例:

data = {
    "labels": ["启用用户", "禁用用户", "总计"],
    "datasets": [{
        "label": "用户分布",
        "data": [300, 50, 100],
        "backgroundColor": [
            "rgb(255, 99, 132)",
            "rgb(54, 162, 235)",
            "rgb(255, 205, 86)"
        ],
        "borderColor": "white",
        "borderWidth": 2,
        "hoverOffset": 15  # 悬停时偏移量
    }]
}

环形图额外配置:

options = {
    "cutout": "50%",  # 环形图空洞大小(百分比)
    "plugins": {
        "legend": {"position": "bottom"},
        "tooltip": {
            "callbacks": {
                "label": "function(context) { return context.label + ': ' + context.parsed + ' (' + context.percentage + '%)'; }"
            }
        }
    }
}

4. 雷达图 (radar)

用于展示多变量数据,比较多个指标。

数据格式示例:

data = {
    "labels": ["产品", "价格", "服务", "质量", "创新"],
    "datasets": [
        {
            "label": "公司A",
            "data": [65, 59, 90, 81, 56],
            "backgroundColor": "rgba(255, 99, 132, 0.2)",
            "borderColor": "rgb(255, 99, 132)",
            "pointBackgroundColor": "rgb(255, 99, 132)"
        },
        {
            "label": "公司B",
            "data": [28, 48, 40, 19, 96],
            "backgroundColor": "rgba(54, 162, 235, 0.2)",
            "borderColor": "rgb(54, 162, 235)",
            "pointBackgroundColor": "rgb(54, 162, 235)"
        }
    ]
}

5. 极区图 (polarArea)

类似于饼图,但扇区角度代表数值比例。

数据格式示例:

data = {
    "labels": ["红色", "蓝色", "黄色", "绿色", "紫色"],
    "datasets": [{
        "label": "颜色分布",
        "data": [11, 16, 7, 3, 14],
        "backgroundColor": [
            "rgb(255, 99, 132)",
            "rgb(54, 162, 235)",
            "rgb(255, 205, 86)",
            "rgb(75, 192, 192)",
            "rgb(153, 102, 255)"
        ]
    }]
}

6. 气泡图 (bubble)

用于展示三维数据(x, y, 半径)。

数据格式示例:

data = {
    "datasets": [{
        "label": "产品A",
        "data": [
            {"x": 20, "y": 30, "r": 15},
            {"x": 40, "y": 10, "r": 10},
            {"x": 30, "y": 20, "r": 25}
        ],
        "backgroundColor": "rgb(255, 99, 132)"
    }]
}

7. 散点图 (scatter)

用于展示两个变量之间的关系。

数据格式示例:

data = {
    "datasets": [{
        "label": "数据集1",
        "data": [
            {"x": -10, "y": 0},
            {"x": 0, "y": 10},
            {"x": 10, "y": 5},
            {"x": 0.5, "y": 5.5}
        ],
        "backgroundColor": "rgb(255, 99, 132)"
    }]
}

数据格式

图表 数据 follows 图表.js format:

    data = {
        "labels": ["Label 1", "Label 2", "Label 3"],  # X-axis labels

        "datasets": [
            {
                "label": "Dataset 1",
                "data": [10, 20, 30],  # Y-axis values

                "borderColor": "rgb(75, 192, 192)",  # Line/border color

                "backgroundColor": "rgba(75, 192, 192, 0.5)",  # Fill color

                # ... other Chart.js dataset properties

            }
        ]
    }

Options 配置

Common 图表.js options:

    options = {
        "responsive": True,
        "maintainAspectRatio": False,
        "plugins": {
            "legend": {
                "position": "top",
                "labels": {
                    "color": "#333",  # Legend text color

                    "font": {
                        "size": 12
                    }
                }
            },
            "title": {
                "display": True,
                "text": "Chart Title",
                "color": "#333",
                "font": {
                    "size": 16,
                    "weight": "bold"
                }
            },
            "tooltip": {
                "enabled": True,
                "mode": "index",
                "intersect": False
            }
        },
        "scales": {
            "x": {
                "grid": {
                    "display": True,
                    "color": "rgba(0, 0, 0, 0.1)"
                },
                "ticks": {
                    "color": "#666"
                }
            },
            "y": {
                "grid": {
                    "display": True,
                    "color": "rgba(0, 0, 0, 0.1)"
                },
                "ticks": {
                    "color": "#666"
                }
            }
        }
    }

深色模式 Support

Charts automatically adapt to 深色模式 when configured:

    def get_context_data(self, request):
        context = super().get_context_data(request)

        # Adapt options for dark mode

        if self.dashboard.is_dark_mode(request):
            if not self.options:
                self.options = {}

            # Dark mode options

            self.options.update({
                "color": "#f9fafb",  # Light text for dark mode

                "plugins": {
                    "legend": {
                        "labels": {
                            "color": "#f9fafb"
                        }
                    }
                },
                "scales": {
                    "x": {
                        "grid": {
                            "color": "#374151"
                        },
                        "ticks": {
                            "color": "#9ca3af"
                        }
                    },
                    "y": {
                        "grid": {
                            "color": "#374151"
                        },
                        "ticks": {
                            "color": "#9ca3af"
                        }
                    }
                }
            })

        return context

表格组件

概述

显示可定制列的表格数据。

    class TableComponent(Component):
        """用于显示表格数据的表格组件"""

        component_type = "table"
        template_name = "admin/components/table.html"

        def __init__(self, title, columns=None, data=None, **kwargs):
            # ... initialization

构造函数参数

参数 类型 默认值 描述
title str 必需 表格标题
columns list [] 列定义
data list [] 行数据
**kwargs any - 额外组件属性

列定义

列可以定义为字符串或字典:

    # Simple column names

    columns = ["ID", "Name", "Email", "Status"]

    # Detailed column definitions

    columns = [
        {"name": "ID", "key": "id", "width": "50px"},
        {"name": "Name", "key": "name", "sortable": True},
        {"name": "Email", "key": "email", "type": "email"},
        {"name": "Status", "key": "status", "type": "badge"},
    ]

数据格式

数据应为匹配列键的字典列表:

    data = [
        {"id": 1, "name": "John Doe", "email": "john@example.com", "status": "active"},
        {"id": 2, "name": "Jane Smith", "email": "jane@example.com", "status": "inactive"},
        # ... more rows

    ]

属性

属性 类型 描述
title str 表格标题
columns list 列定义
data list 行数据

使用 示例

简单 表格

    table = TableComponent(
        title="Recent Users",
        columns=["ID", "Username", "Email", "Date Joined"],
        data=[
            {"ID": 1, "Username": "john_doe", "Email": "john@example.com", "Date Joined": "2024-01-15"},
            {"ID": 2, "Username": "jane_smith", "Email": "jane@example.com", "Date Joined": "2024-01-20"},
        ]
    )

Detailed 表格 配置

    table = TableComponent(
        title="User Management",
        columns=[
            {"name": "ID", "key": "id", "width": "80px", "align": "center"},
            {"name": "Username", "key": "username", "sortable": True, "searchable": True},
            {"name": "Email", "key": "email", "type": "email", "truncate": True},
            {"name": "Status", "key": "status", "type": "badge", "badge_colors": {
                "active": "success",
                "inactive": "secondary",
                "suspended": "danger"
            }},
            {"name": "Actions", "key": "actions", "type": "actions", "actions": [
                {"name": "Edit", "url": "/admin/auth/user/{id}/change/"},
                {"name": "Delete", "url": "/admin/auth/user/{id}/delete/", "confirm": True}
            ]}
        ],
        data=[
            {
                "id": 1,
                "username": "admin",
                "email": "admin@example.com",
                "status": "active",
                "actions": {"id": 1}
            },
            # ... more rows

        ]
    )

动态 表格 数据

    class UserTableComponent(TableComponent):

        def get_context_data(self, request):
            context = super().get_context_data(request)

            # Fetch data dynamically

            users = User.objects.all().order_by('-date_joined')[:10]

            # Format data

            context["data"] = [
                {
                    "id": user.id,
                    "username": user.username,
                    "email": user.email,
                    "status": "active" if user.is_active else "inactive",
                    "date_joined": user.date_joined.strftime("%Y-%m-%d %H:%M"),
                    "last_login": user.last_login.strftime("%Y-%m-%d %H:%M") if user.last_login else "Never"
                }
                for user in users
            ]

            return context

Template Context

表格 components provide the following template context:

    {
        "component": self,
        "component_type": "table",
        "title": self.title,
        "columns": self.columns,
        "data": self.data,
        "table_id": f"table_{id(self)}",  # Unique ID for DOM element

        "has_data": len(self.data) > 0,
        "row_count": len(self.data),
        "column_count": len(self.columns),
    }

列 Types

Supported 列 types and their rendering:

类型 描述 示例
text Plain text (默认) {"type": "text"}
email Email link {"type": "email"}
URL URL link {"type": "URL"}
badge Colored badge {"type": "badge"}
boolean Yes/No or checkmark {"type": "boolean"}
date Formatted date {"type": "date"}
datetime Formatted datetime {"type": "datetime"}
number Formatted number {"type": "number"}
actions Action buttons {"type": "actions"}

列 Options

Common 列 配置 options:

    column = {
        "name": "Column Name",  # Display name

        "key": "field_name",    # Data key

        "type": "text",         # Column type

        "width": "100px",       # Fixed width

        "align": "left",        # Text alignment: left, center, right

        "sortable": True,       # Enable sorting

        "searchable": True,     # Enable searching

        "truncate": True,       # Truncate long text

        "max_length": 50,       # Max length for truncation

        "format": "{:.2f}",     # Format string for numbers

        "date_format": "%Y-%m-%d",  # Date format

        "badge_colors": {       # Color mapping for badges

            "active": "success",
            "inactive": "warning"
        },
        "actions": [            # Actions for action type

            {"name": "Edit", "url": "/edit/{id}/"},
            {"name": "Delete", "url": "/delete/{id}/", "confirm": True}
        ]
    }

深色模式 Support

Tables automatically adapt to 深色模式:

    /* Table dark mode styles in dashboard.css */
    [data-theme="dark"] .dashboard table {
        background-color: #111827;
        color: #f9fafb;
        border-color: #374151;
    }

    [data-theme="dark"] .dashboard table thead {
        background-color: #1f2937;
        border-bottom-color: #374151;
    }

    [data-theme="dark"] .dashboard table th {
        color: #d1d5db;
    }

    [data-theme="dark"] .dashboard table tr:hover {
        background-color: #1f2937;
    }

过滤器组件

概述

创建交互式过滤器控件,支持多种过滤器类型和现代化的下拉面板界面。

主要特性: - 下拉面板设计:过滤器隐藏在触发按钮后的下拉面板中,节省空间 - 多种过滤器类型:支持单选、多选、日期范围、数值范围、文本、数字、复选框等 - Select2集成:所有选择框使用Select2组件,支持搜索功能 - 响应式布局:自适应桌面和移动设备 - 过滤器计数:显示当前应用的过滤器数量 - 浅色UI设计:与Django Admin界面协调的浅灰色按钮样式

    class FilterComponent(Component):
        """过滤器组件"""

        component_type = "filter"
        template_name = "admin/components/filter.html"

        def __init__(self, title, filters=None, **kwargs):
            super().__init__(**kwargs)
            self.title = title
            self.filters = filters or []

        def get_context_data(self, request):
            """获取过滤器组件的上下文数据"""
            context = super().get_context_data(request)
            context.update({
                "filter_id": f"filter_{id(self)}",
                "filters": self.filters,
            })
            return context

构造函数参数

参数 类型 默认值 描述
title str 必需 过滤器区域标题
filters list [] 过滤器定义
**kwargs any - 额外组件属性

过滤器定义

过滤器定义为字典列表,支持以下类型:selectmulti_selectdate_rangetextnumbernumber_rangecheckbox

通用字段: - name: 过滤器字段名称(表单字段名) - label: 显示标签 - type: 过滤器类型 - default: 默认值(可选)

不同类型特有字段:

select 类型: - options: 选项列表,每个选项为 {"value": "...", "label": "..."} 字典 - default: 默认选中的值 - 使用 Select2 组件,支持搜索功能

multi_select 类型: - options: 选项列表,每个选项为 {"value": "...", "label": "..."} 字典 - default: 默认选中的值列表(数组) - 使用 Select2 多选组件,支持搜索和标签显示 - 提交时使用数组参数 name="field_name[]"

date_range 类型: - default: 默认日期范围,可选值:all_timetodayyesterdaylast_7_dayslast_30_daysthis_monthlast_monththis_yearlast_yearcustom - all_time: 表示不应用日期过滤,显示所有时间的数据 - 当选择 custom 时,会显示自定义日期输入框

text 类型: - default: 默认文本值(可选) - placeholder: 占位符文本(可选)

number 类型: - default: 默认数值(可选)

number_range 类型: - min_value: 最小值(可选) - max_value: 最大值(可选) - 提供两个输入框分别输入最小值和最大值 - 支持HTML5 number输入类型

checkbox 类型: - options: 复选框选项列表,每个选项为 {"value": "...", "label": "..."} 字典 - default: 默认选中的值列表(数组)

    filters = [
        {
            "name": "status",
            "label": "状态",
            "type": "select",
            "options": [
                {"value": "all", "label": "全部"},
                {"value": "active", "label": "启用"},
                {"value": "inactive", "label": "禁用"}
            ],
            "default": "all"
        },
        {
            "name": "tags",
            "label": "标签",
            "type": "multi_select",
            "options": [
                {"value": "featured", "label": "精选"},
                {"value": "new", "label": "新品"},
                {"value": "sale", "label": "促销"},
                {"value": "bestseller", "label": "畅销"}
            ],
            "default": []
        },
        {
            "name": "date_range",
            "label": "日期范围",
            "type": "date_range",
            "default": "last_30_days"
        },
        {
            "name": "amount_range",
            "label": "金额范围",
            "type": "number_range",
            "min_value": 0,
            "max_value": 10000
        },
        {
            "name": "search",
            "label": "搜索",
            "type": "text",
            "placeholder": "输入关键词..."
        },
        # ... 更多过滤器
    ]

属性

属性 类型 描述
title str 过滤器 title
filters list 过滤器 definitions

使用 示例

基础过滤器

    filter_component = FilterComponent(
        title="用户过滤器",
        filters=[
            {
                "name": "status",
                "label": "用户状态",
                "type": "select",
                "options": [
                    {"value": "all", "label": "全部用户"},
                    {"value": "active", "label": "仅启用用户"},
                    {"value": "inactive", "label": "仅禁用用户"}
                ],
                "default": "all"
            },
            {
                "name": "role",
                "label": "用户角色",
                "type": "select",
                "options": [
                    {"value": "all", "label": "全部角色"},
                    {"value": "admin", "label": "管理员"},
                    {"value": "user", "label": "普通用户"}
                ],
                "default": "all"
            },
            {
                "name": "search",
                "label": "搜索",
                "type": "text",
                "placeholder": "按姓名或邮箱搜索..."
            }
        ]
    )

日期范围过滤器

    filter_component = FilterComponent(
        title="日期过滤器",
        filters=[
            {
                "name": "date_range",
                "label": "日期范围",
                "type": "date_range",
                "default": "last_30_days"
            }
        ]
    )

多种过滤器类型示例

    filter_component = FilterComponent(
        title="综合过滤器",
        filters=[
            {
                "name": "category",
                "label": "分类",
                "type": "select",
                "options": [
                    {"value": "all", "label": "全部分类"},
                    {"value": "tech", "label": "技术"},
                    {"value": "business", "label": "商业"},
                    {"value": "science", "label": "科学"}
                ],
                "default": "all"
            },
            {
                "name": "price_range",
                "label": "价格范围",
                "type": "number",
                "default": 100
            },
            {
                "name": "tags",
                "label": "标签",
                "type": "checkbox",
                "options": [
                    {"value": "new", "label": "新品"},
                    {"value": "popular", "label": "热门"},
                    {"value": "featured", "label": "推荐"}
                ],
                "default": ["new"]
            },
            {
                "name": "date_range",
                "label": "发布日期",
                "type": "date_range",
                "default": "this_month"
            }
        ]
    )

动态 过滤器 Options

    class DynamicFilterComponent(FilterComponent):

        def get_context_data(self, request):
            context = super().get_context_data(request)

            # Generate filter options dynamically

            user_groups = Group.objects.all()

            context["filters"] = [
                {
                    "name": "group",
                    "label": "User Group",
                    "type": "select",
                    "options": [
                        {"value": "", "label": "All Groups"}
                    ] + [
                        {"value": str(group.id), "label": group.name}
                        for group in user_groups
                    ]
                }
            ]

            return context

Template Context

过滤器 components provide the following template context:

    {
        "component": self,
        "component_type": "filter",
        "title": self.title,
        "filters": self.filters,
        "filter_id": f"filter_{id(self)}",  # Unique ID for DOM element

        "has_filters": len(self.filters) > 0,
    }

过滤器 Types

Supported 过滤器 types:

类型 描述 HTML元素
text Text input <input type="text">
select Dropdown select <select>
multiselect Multiple selection <select multiple>
checkbox Checkbox <input type="checkbox">
radio Radio buttons <input type="radio">
daterange Date range picker Two date inputs
date Single date picker <input type="date">
number Number input <input type="number">
range Range slider <input type="range">

过滤器 Options

Common 过滤器 配置 options:

    filter = {
        "name": "field_name",      # Query parameter name

        "label": "Filter Label",   # Display label

        "type": "select",          # Filter type

        "options": [               # Options for select types

            {"value": "", "label": "All"},
            {"value": "option1", "label": "Option 1"}
        ],
        "default": "",             # Default value

        "placeholder": "Type here...",  # Placeholder for text inputs

        "required": False,         # Required field

        "multiple": False,         # Multiple selection for selects

        "min": 0,                  # Minimum value for number/range

        "max": 100,                # Maximum value for number/range

        "step": 1,                 # Step for number/range

        "format": "YYYY-MM-DD",    # Date format for date inputs

        "ranges": {                # Predefined ranges for daterange

            "Today": [today, today],
            "Last 7 Days": [today - timedelta(days=6), today]
        }
    }

JavaScript Integration

过滤器 components include JavaScript for interactivity:

    // Filter component JavaScript
    document.addEventListener('DOMContentLoaded', function() {
        const filterForm = document.querySelector('.dashboard-filter-form');

        if (filterForm) {
            // Handle filter changes
            filterForm.addEventListener('change', function() {
                applyFilters();
            });

            // Handle filter submission
            filterForm.addEventListener('submit', function(e) {
                e.preventDefault();
                applyFilters();
            });

            function applyFilters() {
                const formData = new FormData(filterForm);
                const params = new URLSearchParams();

                // Build query parameters
                for (const [key, value] of formData.entries()) {
                    if (value) {
                        params.append(key, value);
                    }
                }

                // Update URL without reload
                const newUrl = window.location.pathname + '?' + params.toString();
                window.history.pushState({}, '', newUrl);

                // Dispatch filter change event
                window.dispatchEvent(new CustomEvent('dashboardfilterchange', {
                    detail: { params: Object.fromEntries(params) }
                }));
            }
        }
    });

自定义组件

创建自定义组件

扩展基础 Component 类以创建自定义组件:

    from django_admin_dashboards.base import Component

    class CustomComponent(Component):
        """Custom component example"""

        component_type = "custom"
        template_name = "admin/components/custom.html"

        def __init__(self, title, data=None, **kwargs):
            super().__init__(**kwargs)
            self.title = title
            self.data = data or []

        def get_context_data(self, request):
            context = super().get_context_data(request)

            # Add custom context

            context.update({
                "title": self.title,
                "data": self.data,
                "processed_data": self.process_data(),
                "user": request.user if request else None,
            })

            return context

        def process_data(self):
            """Process data for display"""
            return [item.upper() for item in self.data]

Template for 自定义 组件

创建 a template at admin/components/自定义.HTML:

    <div class="dashboard-component custom-component">
        <div class="component-header">
            <h3>{{ title }}</h3>
        </div>

        <div class="component-body">
            {% if data %}
                <ul>
                    {% for item in processed_data %}
                        <li>{{ item }}</li>
                    {% endfor %}
                </ul>
            {% else %}
                <p class="text-muted">No data available</p>
            {% endif %}
        </div>

        <div class="component-footer">
            <small>Displaying {{ data|length }} items</small>
        </div>
    </div>

注册自定义组件

在数据看板中使用自定义组件:

    from .components import CustomComponent

    class MyDashboard(Dashboard):

        def get_layout(self):
            layout = Layout(columns=12)

            custom = CustomComponent(
                title="Custom Data",
                data=["item1", "item2", "item3"]
            )

            layout.add_component(custom, width=12)
            return layout

高级 自定义 组件

创建 components with 复杂 behavior:

    class InteractiveChartComponent(Component):
        """Interactive chart with server-side data"""

        component_type = "interactive_chart"
        template_name = "admin/components/interactive_chart.html"

        def __init__(self, title, endpoint, **kwargs):
            super().__init__(**kwargs)
            self.title = title
            self.endpoint = endpoint
            self.chart_type = kwargs.get('chart_type', 'line')

        def get_context_data(self, request):
            context = super().get_context_data(request)

            # Add AJAX endpoint

            context['endpoint'] = self.endpoint

            # Add initial data if needed

            if hasattr(self, 'get_initial_data'):
                context['initial_data'] = self.get_initial_data(request)

            # Add chart configuration

            context['chart_config'] = {
                'type': self.chart_type,
                'options': {
                    'responsive': True,
                    'maintainAspectRatio': False,
                }
            }

            return context

        @classmethod
        def handle_ajax_request(cls, request, component_id):
            """Handle AJAX data requests"""
            # Parse component ID and parameters

            params = request.GET

            # Fetch data based on parameters

            data = cls.fetch_data(params)

            return JsonResponse(data)

组件生命周期

初始化

  1. 组件创建: Component(**kwargs) 构造函数被调用
  2. 属性设置: 所有关键字参数设置为实例属性
  3. 上下文准备: 模板上下文初始化

上下文构建

  1. 请求处理: get_context_data(request) 被调用
  2. 数据获取: 组件检索必要的数据
  3. 上下文增强: 根据需要添加额外上下文

模板渲染

  1. 模板选择: template_name 用于查找模板
  2. 上下文注入: 上下文字典传递给模板
  3. HTML生成: 模板渲染为HTML

数据看板 Integration

  1. 布局添加: 组件添加到数据看板布局
  2. 上下文合并: 数据看板合并组件上下文
  3. 渲染: 数据看板模板包含组件模板

最佳实践

1. 保持组件专注

    # Good: Single responsibility

    class UserCountCard(CardComponent):
        """Card showing user count"""
        pass

    # Avoid: Multiple responsibilities

    class UserDashboardCard(Component):
        """Card showing user count, recent activity, and messages"""
        pass

2. 使用描述性属性名称

    # Good

    card = CardComponent(
        title="Monthly Revenue",
        value=50000,
        currency="USD",
        trend="up"
    )

    # Avoid

    card = CardComponent(
        t="Rev",
        v=50000,
        c="USD",
        tr="u"
    )

3. 优雅处理缺失数据

    def get_context_data(self, request):
        context = super().get_context_data(request)

        try:
            context['data'] = self.fetch_data()
        except (DatabaseError, ConnectionError) as e:
            context['data'] = []
            context['error'] = str(e)
            context['has_error'] = True

        return context

4. 优化数据获取

    class OptimizedChartComponent(ChartComponent):

        def get_context_data(self, request):
            context = super().get_context_data(request)

            # Cache data fetching

            cache_key = f"chart_data_{self.chart_type}_{request.user.pk}"
            data = cache.get(cache_key)

            if not data:
                data = self.fetch_expensive_data()
                cache.set(cache_key, data, timeout=300)  # 5 minutes

            context['data'] = data
            return context

5. 测试 Components

    from django.test import TestCase
    from django.test.client import RequestFactory

    class ComponentTests(TestCase):

        def test_card_component(self):
            card = CardComponent(title="Test", value=100)
            self.assertEqual(card.title, "Test")
            self.assertEqual(card.value, 100)

        def test_component_context(self):
            factory = RequestFactory()
            request = factory.get('/')

            component = CardComponent(title="Test", value=100)
            context = component.get_context_data(request)

            self.assertIn('component', context)
            self.assertIn('title', context)

6. 文档化组件使用

    class DocumentedComponent(Component):
        """
        用于显示用户统计信息的组件。

        参数:
        - title (str): 组件标题
        - user_ids (list): 要包含的用户ID列表
        - timeframe (str): 时间段:'day', 'week', 'month'

        使用示例:
        >>> component = DocumentedComponent(
        ...     title="User Activity",
        ...     user_ids=[1, 2, 3],
        ...     timeframe="week"
        ... )
        """

        def __init__(self, title, user_ids=None, timeframe='day', **kwargs):
            super().__init__(**kwargs)
            self.title = title
            self.user_ids = user_ids or []
            self.timeframe = timeframe