unfold-admin by 0xdarkmatter/claude-mods
npx skills add https://github.com/0xdarkmatter/claude-mods --skill unfold-admin基于 Tailwind CSS、HTMX 和 Alpine.js 的现代 Django 管理后台主题。用精致、功能丰富的界面替换 Django 默认的管理后台。
# settings.py - unfold 必须在 django.contrib.admin 之前
INSTALLED_APPS = [
"unfold",
"unfold.contrib.filters", # 高级过滤器
"unfold.contrib.forms", # 数组/富文本编辑器组件
"unfold.contrib.inlines", # 非关联内联
"unfold.contrib.import_export", # 样式化的导入/导出
"unfold.contrib.guardian", # django-guardian 集成
"unfold.contrib.simple_history", # django-simple-history 集成
"unfold.contrib.constance", # django-constance 集成
"unfold.contrib.location_field", # django-location-field 集成
# ...
"django.contrib.admin",
]
from unfold.admin import ModelAdmin
@admin.register(MyModel)
class MyModelAdmin(ModelAdmin):
pass # 继承 Unfold 样式
替换默认的 AdminSite 或通过 settings 中的 UNFOLD 字典进行配置。完整的设置参考请查看 references/configuration.md。
Modern Django admin theme with Tailwind CSS, HTMX, and Alpine.js. Replaces Django's default admin with a polished, feature-rich interface.
# settings.py - unfold MUST be before django.contrib.admin
INSTALLED_APPS = [
"unfold",
"unfold.contrib.filters", # advanced filters
"unfold.contrib.forms", # array/wysiwyg widgets
"unfold.contrib.inlines", # nonrelated inlines
"unfold.contrib.import_export", # styled import/export
"unfold.contrib.guardian", # django-guardian integration
"unfold.contrib.simple_history", # django-simple-history integration
"unfold.contrib.constance", # django-constance integration
"unfold.contrib.location_field", # django-location-field integration
# ...
"django.contrib.admin",
]
from unfold.admin import ModelAdmin
@admin.register(MyModel)
class MyModelAdmin(ModelAdmin):
pass # inherits Unfold styling
Replace the default AdminSite or configure via dict in settings. See for the complete settings reference.
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
UNFOLD = {
"SITE_TITLE": "我的管理后台",
"SITE_HEADER": "我的管理后台",
"SITE_SYMBOL": "dashboard", # Material Symbols 图标名称
"SIDEBAR": {
"show_search": True,
"navigation": [
{
"title": _("导航"),
"items": [
{
"title": _("仪表盘"),
"icon": "dashboard",
"link": reverse_lazy("admin:index"),
},
],
},
],
},
}
构建 Unfold 管理后台界面时,请遵循以下顺序:
unfold.admin.ModelAdmin@display 装饰器处理列表列@action 装饰器处理行/列表/详情/提交操作formfield_overrides 应用 Unfold 组件@register_component + BaseComponent 创建 KPI 卡片Unfold 扩展了 Django 的 ModelAdmin,增加了以下属性:
| 属性 | 类型 | 用途 |
|---|---|---|
list_fullwidth | bool | 全宽变更列表(无侧边栏) |
list_filter_submit | bool | 为过滤器添加提交按钮 |
list_filter_sheet | bool | 滑动面板中的过滤器 |
compressed_fields | bool | 表单中紧凑的字段间距 |
warn_unsaved_form | bool | 离开未保存表单前警告 |
ordering_field | str | 拖拽排序的字段名 |
hide_ordering_field | bool | 隐藏排序字段列 |
list_horizontal_scrollbar_top | bool | 列表顶部的滚动条 |
list_disable_select_all | bool | 禁用“全选”复选框 |
change_form_show_cancel_button | bool | 表单上显示取消按钮 |
actions_list | list | 全局变更列表操作 |
actions_row | list | 变更列表中的每行操作 |
actions_detail | list | 变更表单上的操作 |
actions_submit_line | list | 表单提交区域的操作 |
actions_list_hide_default | bool | 隐藏默认列表操作 |
actions_detail_hide_default | bool | 隐藏默认详情操作 |
conditional_fields | dict | 字段可见性的 JS 表达式 |
change_form_datasets | list | 变更表单的 BaseDataset 子类 |
list_sections | list | 列表的 TableSection/TemplateSection |
list_sections_classes | str | 区块的 CSS 网格类 |
readonly_preprocess_fields | dict | 转换只读字段内容 |
add_fieldsets | list | 添加表单的独立字段集(类似 UserAdmin) |
在变更列表或变更表单前后插入自定义 HTML:
class MyAdmin(ModelAdmin):
# 变更列表
list_before_template = "myapp/list_before.html"
list_after_template = "myapp/list_after.html"
# 变更表单(在 <form> 标签内)
change_form_before_template = "myapp/form_before.html"
change_form_after_template = "myapp/form_after.html"
# 变更表单(在 <form> 标签外)
change_form_outer_before_template = "myapp/outer_before.html"
change_form_outer_after_template = "myapp/outer_after.html"
根据其他字段值显示/隐藏字段(Alpine.js 表达式):
class MyAdmin(ModelAdmin):
conditional_fields = {
"premium_features": "plan == 'PRO'",
"discount_amount": "has_discount == true",
}
四种操作类型,每种都有不同的签名。完整参考请查看 references/actions-filters.md。
from unfold.decorators import action
from unfold.enums import ActionVariant
# 列表操作(无对象上下文)
@action(description=_("重建索引"), icon="sync", variant=ActionVariant.PRIMARY)
def rebuild_index(self, request):
# 处理...
return redirect(request.headers["referer"])
# 行操作(接收 object_id)
@action(description=_("批准"), url_path="approve")
def approve_row(self, request, object_id):
obj = self.model.objects.get(pk=object_id)
return redirect(request.headers["referer"])
# 详情操作(接收 object_id,显示在变更表单上)
@action(description=_("发送邮件"), permissions=["send_email"])
def send_email(self, request, object_id):
return redirect(reverse_lazy("admin:myapp_mymodel_change", args=[object_id]))
# 提交行操作(接收 obj 实例,保存时运行)
@action(description=_("保存并发布"))
def save_and_publish(self, request, obj):
obj.published = True
actions_list = [
"primary_action",
{
"title": _("更多"),
"variant": ActionVariant.PRIMARY,
"items": ["secondary_action", "tertiary_action"],
},
]
@action(permissions=["can_export", "auth.view_user"])
def export_data(self, request):
pass
def has_can_export_permission(self, request):
return request.user.is_superuser
增强 list_display 列。请查看 references/actions-filters.md。
from unfold.decorators import display
# 彩色状态标签
@display(description=_("状态"), ordering="status", label={
"active": "success", # 绿色
"pending": "info", # 蓝色
"warning": "warning", # 橙色
"inactive": "danger", # 红色
})
def show_status(self, obj):
return obj.status
# 带头像的丰富标题
@display(description=_("用户"), header=True)
def show_header(self, obj):
return [
obj.full_name, # 主要文本
obj.email, # 次要文本
obj.initials, # 徽章文本
{"path": obj.avatar.url, "width": 24, "height": 24, "borderless": True},
]
# 交互式下拉菜单
@display(description=_("团队"), dropdown=True)
def show_teams(self, obj):
return {
"title": f"{obj.teams.count()} 个团队",
"items": [{"title": t.name, "link": t.get_admin_url()} for t in obj.teams.all()],
"striped": True,
"max_height": 200,
}
# 布尔值勾选标记
@display(description=_("活跃"), boolean=True)
def is_active(self, obj):
return obj.is_active
Unfold 提供高级过滤器类。请查看 references/actions-filters.md。
from unfold.contrib.filters.admin import (
TextFilter, RangeNumericFilter, RangeDateFilter, RangeDateTimeFilter,
SingleNumericFilter, SliderNumericFilter, RelatedDropdownFilter,
RelatedCheckboxFilter, ChoicesCheckboxFilter, AllValuesCheckboxFilter,
BooleanRadioFilter, CheckboxFilter, AutocompleteSelectMultipleFilter,
)
class MyAdmin(ModelAdmin):
list_filter_submit = True # 基于输入的过滤器需要此设置
list_filter = [
("salary", RangeNumericFilter),
("status", ChoicesCheckboxFilter),
("created_at", RangeDateFilter),
("category", RelatedDropdownFilter),
("is_active", BooleanRadioFilter),
]
class NameFilter(TextFilter):
title = _("名称")
parameter_name = "name"
def queryset(self, request, queryset):
if self.value() in EMPTY_VALUES:
return queryset
return queryset.filter(name__icontains=self.value())
为 Unfold 样式覆盖表单组件。请查看 references/widgets-inlines.md。
from unfold.widgets import (
UnfoldAdminTextInputWidget, UnfoldAdminSelectWidget, UnfoldAdminSelect2Widget,
UnfoldBooleanSwitchWidget, UnfoldAdminColorInputWidget,
UnfoldAdminSplitDateTimeWidget, UnfoldAdminImageFieldWidget,
)
from unfold.contrib.forms.widgets import WysiwygWidget, ArrayWidget
class MyAdmin(ModelAdmin):
formfield_overrides = {
models.TextField: {"widget": WysiwygWidget},
models.ImageField: {"widget": UnfoldAdminImageFieldWidget},
}
widget = UnfoldAdminTextInputWidget(attrs={
"prefix_icon": "search",
"suffix_icon": "euro",
})
Unfold 内联支持标签页、分页、排序和非关联模型。请查看 references/widgets-inlines.md。
from unfold.admin import TabularInline, StackedInline
from unfold.contrib.inlines.admin import NonrelatedStackedInline
class OrderItemInline(TabularInline):
model = OrderItem
tab = True # 显示为标签页
per_page = 10 # 分页
ordering_field = "weight" # 拖拽排序
hide_title = True
collapsible = True
使用 "classes": ["tab"] 将字段集分组到标签页中:
fieldsets = [
(None, {"fields": ["name", "email"]}), # 始终可见
(_("个人资料"), {"classes": ["tab"], "fields": ["bio", "avatar"]}),
(_("设置"), {"classes": ["tab"], "fields": ["theme", "notifications"]}),
]
构建 KPI 卡片和自定义仪表盘组件。请查看 references/dashboard.md。
from unfold.components import BaseComponent, register_component
from django.template.loader import render_to_string
@register_component
class ActiveUsersComponent(BaseComponent):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["children"] = render_to_string("myapp/kpi_card.html", {
"total": User.objects.filter(is_active=True).count(),
"label": "活跃用户",
})
return context
在设置中配置:
UNFOLD = {
"DASHBOARD_CALLBACK": "myapp.views.dashboard_callback",
}
在变更列表视图中嵌入相关数据面板:
from unfold.sections import TableSection, TemplateSection
class RecentOrdersSection(TableSection):
related_name = "order_set"
fields = ["id", "total", "status"]
height = 380
class ChartSection(TemplateSection):
template_name = "myapp/chart.html"
class MyAdmin(ModelAdmin):
list_sections = [RecentOrdersSection, ChartSection]
list_sections_classes = "lg:grid-cols-2"
在变更表单中嵌入模型列表:
from unfold.datasets import BaseDataset
class RelatedItemsDatasetAdmin(ModelAdmin):
list_display = ["name", "status"]
search_fields = ["name"]
class RelatedItemsDataset(BaseDataset):
model = RelatedItem
model_admin = RelatedItemsDatasetAdmin
tab = True # 显示为标签页
class MyAdmin(ModelAdmin):
change_form_datasets = [RelatedItemsDataset]
使用无限滚动分页:
from unfold.paginator import InfinitePaginator
class MyAdmin(ModelAdmin):
paginator = InfinitePaginator
show_full_result_count = False
list_per_page = 20
Unfold 为常见的 Django 包提供样式化包装器。完整的设置指南请查看 references/resources.md。
| 包 | Unfold 模块 | 设置 |
|---|---|---|
| django-import-export | unfold.contrib.import_export | 使用 ImportForm, ExportForm, SelectableFieldsExportForm |
| django-guardian | unfold.contrib.guardian | 样式化的 guardian 集成 |
| django-simple-history | unfold.contrib.simple_history | 样式化的历史记录集成 |
| django-constance | unfold.contrib.constance | 样式化的 constance 配置 |
| django-location-field | unfold.contrib.location_field | 位置组件 |
| django-modeltranslation | 兼容 | 将 TabbedTranslationAdmin 与 ModelAdmin 混合 |
| django-celery-beat | 兼容(重新注册) | 注销 5 个模型,用 Unfold 重新注册 |
| django-money | unfold.widgets | UnfoldAdminMoneyWidget |
| djangoql | 兼容 | 将 DjangoQLSearchMixin 与 ModelAdmin 混合 |
| django-crispy-forms | 兼容 | 提供 Unfold 模板包 |
# 多重继承 - Unfold ModelAdmin 始终在最后
@admin.register(MyModel)
class MyAdmin(DjangoQLSearchMixin, SimpleHistoryAdmin, GuardedModelAdmin, ModelAdmin):
pass
Unfold 提供可重用的模板组件,用于仪表盘和自定义页面:
| 组件 | 路径 | 关键变量 |
|---|---|---|
| 卡片 | unfold/components/card.html | title, footer, label, icon |
| 条形图 | unfold/components/chart/bar.html | data (JSON), height, width |
| 折线图 | unfold/components/chart/line.html | data (JSON), height, width |
| 进度条 | unfold/components/progress.html | value, title, description |
| 表格 | unfold/components/table.html | table, card_included, striped |
| 按钮 | unfold/components/button.html | name, href, submit |
| 追踪器 | unfold/components/tracker.html | data |
| 队列 | unfold/components/cohort.html | data |
{% load unfold %}
{% component "MyKPIComponent" %}{% endcomponent %}
Unfold 提供 Django 身份验证管理表单的样式化版本:
from unfold.forms import AdminPasswordChangeForm, UserChangeForm, UserCreationForm
@admin.register(User)
class UserAdmin(BaseUserAdmin, ModelAdmin):
form = UserChangeForm
add_form = UserCreationForm
change_password_form = AdminPasswordChangeForm
按主题划分的详细文档:
当您需要特定功能领域的详细配置选项、可用类的完整列表、完整的代码示例或集成设置指南时,请阅读相关的参考文件。
| 资源 | URL |
|---|---|
| 文档 | https://unfoldadmin.com/docs/ |
| GitHub | https://github.com/unfoldadmin/django-unfold |
| 演示应用(Formula) | https://github.com/unfoldadmin/formula |
| 在线演示 | https://demo.unfoldadmin.com |
| Material Symbols(图标) | https://fonts.google.com/icons |
当不确定实现模式时,请查阅 Formula 演示仓库中的 formula/admin.py 和 formula/settings.py - 它几乎涵盖了所有 Unfold 功能。
每周安装数
6
仓库
GitHub 星标数
8
首次出现
2026年2月21日
安全审计
安装于
gemini-cli6
amp6
claude-code6
github-copilot6
codex6
kimi-cli6
UNFOLDUNFOLD = {
"SITE_TITLE": "My Admin",
"SITE_HEADER": "My Admin",
"SITE_SYMBOL": "dashboard", # Material Symbols icon name
"SIDEBAR": {
"show_search": True,
"navigation": [
{
"title": _("Navigation"),
"items": [
{
"title": _("Dashboard"),
"icon": "dashboard",
"link": reverse_lazy("admin:index"),
},
],
},
],
},
}
When building Unfold admin interfaces, follow this sequence:
unfold.admin.ModelAdmin@display decorator for list columns@action decorator for row/list/detail/submit actionsformfield_overrides@register_component + BaseComponent for KPI cardsUnfold extends Django's ModelAdmin with these additional attributes:
| Attribute | Type | Purpose |
|---|---|---|
list_fullwidth | bool | Full-width changelist (no sidebar) |
list_filter_submit | bool | Add submit button to filters |
list_filter_sheet | bool | Filters in sliding sheet panel |
compressed_fields | bool | Compact field spacing in forms |
warn_unsaved_form | bool | Warn before leaving unsaved form |
ordering_field | str | Field name for drag-to-reorder |
hide_ordering_field | bool | Hide the ordering field column |
list_horizontal_scrollbar_top | bool | Scrollbar at top of list |
list_disable_select_all | bool | Disable "select all" checkbox |
change_form_show_cancel_button | bool | Show cancel button on form |
actions_list | list | Global changelist actions |
actions_row | list | Per-row actions in changelist |
actions_detail | list | Actions on change form |
actions_submit_line | list | Actions in form submit area |
actions_list_hide_default | bool | Hide default list actions |
actions_detail_hide_default | bool | Hide default detail actions |
conditional_fields | dict | JS expressions for field visibility |
change_form_datasets | list | BaseDataset subclasses for change form |
list_sections | list | TableSection/TemplateSection for list |
list_sections_classes | str | CSS grid classes for sections |
readonly_preprocess_fields | dict | Transform readonly field content |
add_fieldsets | list | Separate fieldsets for add form (like UserAdmin) |
Insert custom HTML before/after changelist or change form:
class MyAdmin(ModelAdmin):
# Changelist
list_before_template = "myapp/list_before.html"
list_after_template = "myapp/list_after.html"
# Change form (inside <form> tag)
change_form_before_template = "myapp/form_before.html"
change_form_after_template = "myapp/form_after.html"
# Change form (outside <form> tag)
change_form_outer_before_template = "myapp/outer_before.html"
change_form_outer_after_template = "myapp/outer_after.html"
Show/hide fields based on other field values (Alpine.js expressions):
class MyAdmin(ModelAdmin):
conditional_fields = {
"premium_features": "plan == 'PRO'",
"discount_amount": "has_discount == true",
}
Four action types, each with different signatures. See references/actions-filters.md for complete reference.
from unfold.decorators import action
from unfold.enums import ActionVariant
# List action (no object context)
@action(description=_("Rebuild Index"), icon="sync", variant=ActionVariant.PRIMARY)
def rebuild_index(self, request):
# process...
return redirect(request.headers["referer"])
# Row action (receives object_id)
@action(description=_("Approve"), url_path="approve")
def approve_row(self, request, object_id):
obj = self.model.objects.get(pk=object_id)
return redirect(request.headers["referer"])
# Detail action (receives object_id, shown on change form)
@action(description=_("Send Email"), permissions=["send_email"])
def send_email(self, request, object_id):
return redirect(reverse_lazy("admin:myapp_mymodel_change", args=[object_id]))
# Submit line action (receives obj instance, runs on save)
@action(description=_("Save & Publish"))
def save_and_publish(self, request, obj):
obj.published = True
actions_list = [
"primary_action",
{
"title": _("More"),
"variant": ActionVariant.PRIMARY,
"items": ["secondary_action", "tertiary_action"],
},
]
@action(permissions=["can_export", "auth.view_user"])
def export_data(self, request):
pass
def has_can_export_permission(self, request):
return request.user.is_superuser
Enhance list_display columns. See references/actions-filters.md.
from unfold.decorators import display
# Colored status labels
@display(description=_("Status"), ordering="status", label={
"active": "success", # green
"pending": "info", # blue
"warning": "warning", # orange
"inactive": "danger", # red
})
def show_status(self, obj):
return obj.status
# Rich header with avatar
@display(description=_("User"), header=True)
def show_header(self, obj):
return [
obj.full_name, # primary text
obj.email, # secondary text
obj.initials, # badge text
{"path": obj.avatar.url, "width": 24, "height": 24, "borderless": True},
]
# Interactive dropdown
@display(description=_("Teams"), dropdown=True)
def show_teams(self, obj):
return {
"title": f"{obj.teams.count()} teams",
"items": [{"title": t.name, "link": t.get_admin_url()} for t in obj.teams.all()],
"striped": True,
"max_height": 200,
}
# Boolean checkmark
@display(description=_("Active"), boolean=True)
def is_active(self, obj):
return obj.is_active
Unfold provides advanced filter classes. See references/actions-filters.md.
from unfold.contrib.filters.admin import (
TextFilter, RangeNumericFilter, RangeDateFilter, RangeDateTimeFilter,
SingleNumericFilter, SliderNumericFilter, RelatedDropdownFilter,
RelatedCheckboxFilter, ChoicesCheckboxFilter, AllValuesCheckboxFilter,
BooleanRadioFilter, CheckboxFilter, AutocompleteSelectMultipleFilter,
)
class MyAdmin(ModelAdmin):
list_filter_submit = True # required for input-based filters
list_filter = [
("salary", RangeNumericFilter),
("status", ChoicesCheckboxFilter),
("created_at", RangeDateFilter),
("category", RelatedDropdownFilter),
("is_active", BooleanRadioFilter),
]
class NameFilter(TextFilter):
title = _("Name")
parameter_name = "name"
def queryset(self, request, queryset):
if self.value() in EMPTY_VALUES:
return queryset
return queryset.filter(name__icontains=self.value())
Override form widgets for Unfold styling. See references/widgets-inlines.md.
from unfold.widgets import (
UnfoldAdminTextInputWidget, UnfoldAdminSelectWidget, UnfoldAdminSelect2Widget,
UnfoldBooleanSwitchWidget, UnfoldAdminColorInputWidget,
UnfoldAdminSplitDateTimeWidget, UnfoldAdminImageFieldWidget,
)
from unfold.contrib.forms.widgets import WysiwygWidget, ArrayWidget
class MyAdmin(ModelAdmin):
formfield_overrides = {
models.TextField: {"widget": WysiwygWidget},
models.ImageField: {"widget": UnfoldAdminImageFieldWidget},
}
widget = UnfoldAdminTextInputWidget(attrs={
"prefix_icon": "search",
"suffix_icon": "euro",
})
Unfold inlines support tabs, pagination, sorting, and nonrelated models. See references/widgets-inlines.md.
from unfold.admin import TabularInline, StackedInline
from unfold.contrib.inlines.admin import NonrelatedStackedInline
class OrderItemInline(TabularInline):
model = OrderItem
tab = True # show as tab
per_page = 10 # paginated
ordering_field = "weight" # drag-to-reorder
hide_title = True
collapsible = True
Group fieldsets into tabs using "classes": ["tab"]:
fieldsets = [
(None, {"fields": ["name", "email"]}), # always visible
(_("Profile"), {"classes": ["tab"], "fields": ["bio", "avatar"]}),
(_("Settings"), {"classes": ["tab"], "fields": ["theme", "notifications"]}),
]
Build KPI cards and custom dashboard widgets. See references/dashboard.md.
from unfold.components import BaseComponent, register_component
from django.template.loader import render_to_string
@register_component
class ActiveUsersComponent(BaseComponent):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["children"] = render_to_string("myapp/kpi_card.html", {
"total": User.objects.filter(is_active=True).count(),
"label": "Active Users",
})
return context
Configure in settings:
UNFOLD = {
"DASHBOARD_CALLBACK": "myapp.views.dashboard_callback",
}
Embed related data panels in changelist views:
from unfold.sections import TableSection, TemplateSection
class RecentOrdersSection(TableSection):
related_name = "order_set"
fields = ["id", "total", "status"]
height = 380
class ChartSection(TemplateSection):
template_name = "myapp/chart.html"
class MyAdmin(ModelAdmin):
list_sections = [RecentOrdersSection, ChartSection]
list_sections_classes = "lg:grid-cols-2"
Embed model listings within change forms:
from unfold.datasets import BaseDataset
class RelatedItemsDatasetAdmin(ModelAdmin):
list_display = ["name", "status"]
search_fields = ["name"]
class RelatedItemsDataset(BaseDataset):
model = RelatedItem
model_admin = RelatedItemsDatasetAdmin
tab = True # show as tab
class MyAdmin(ModelAdmin):
change_form_datasets = [RelatedItemsDataset]
Use infinite scroll pagination:
from unfold.paginator import InfinitePaginator
class MyAdmin(ModelAdmin):
paginator = InfinitePaginator
show_full_result_count = False
list_per_page = 20
Unfold provides styled wrappers for common Django packages. See references/resources.md for complete setup guides.
| Package | Unfold Module | Setup |
|---|---|---|
| django-import-export | unfold.contrib.import_export | Use ImportForm, ExportForm, SelectableFieldsExportForm |
| django-guardian | unfold.contrib.guardian | Styled guardian integration |
| django-simple-history | unfold.contrib.simple_history | Styled history integration |
| django-constance | unfold.contrib.constance | Styled constance config |
| django-location-field | unfold.contrib.location_field | Location widget |
| django-modeltranslation | Compatible | Mix TabbedTranslationAdmin with ModelAdmin |
| django-celery-beat | Compatible (rewire) | Unregister 5 models, re-register with Unfold |
| django-money | unfold.widgets | UnfoldAdminMoneyWidget |
| djangoql | Compatible | Mix DjangoQLSearchMixin with ModelAdmin |
| django-crispy-forms | Compatible | Unfold template pack available |
# Multiple inheritance - Unfold ModelAdmin always last
@admin.register(MyModel)
class MyAdmin(DjangoQLSearchMixin, SimpleHistoryAdmin, GuardedModelAdmin, ModelAdmin):
pass
Unfold ships reusable template components for dashboards and custom pages:
| Component | Path | Key Variables |
|---|---|---|
| Card | unfold/components/card.html | title, footer, label, icon |
| Bar Chart | unfold/components/chart/bar.html | data (JSON), height, width |
| Line Chart | unfold/components/chart/line.html | data (JSON), height, width |
| Progress | unfold/components/progress.html | value, title, description |
| Table | unfold/components/table.html | table, card_included, striped |
| Button | unfold/components/button.html | name, href, submit |
| Tracker | unfold/components/tracker.html | data |
| Cohort | unfold/components/cohort.html | data |
{% load unfold %}
{% component "MyKPIComponent" %}{% endcomponent %}
Unfold provides styled versions of Django's auth admin forms:
from unfold.forms import AdminPasswordChangeForm, UserChangeForm, UserCreationForm
@admin.register(User)
class UserAdmin(BaseUserAdmin, ModelAdmin):
form = UserChangeForm
add_form = UserCreationForm
change_password_form = AdminPasswordChangeForm
Detailed documentation split by topic:
Read the relevant reference file when you need detailed configuration options, the full list of available classes, complete code examples, or integration setup guides for a specific feature area.
| Resource | URL |
|---|---|
| Docs | https://unfoldadmin.com/docs/ |
| GitHub | https://github.com/unfoldadmin/django-unfold |
| Demo App (Formula) | https://github.com/unfoldadmin/formula |
| Live Demo | https://demo.unfoldadmin.com |
| Material Symbols (Icons) | https://fonts.google.com/icons |
When uncertain about an implementation pattern, consult formula/admin.py and formula/settings.py in the Formula demo repo - it covers virtually every Unfold feature.
Weekly Installs
6
Repository
GitHub Stars
8
First Seen
Feb 21, 2026
Security Audits
Installed on
gemini-cli6
amp6
claude-code6
github-copilot6
codex6
kimi-cli6
React Router 框架模式指南:全栈开发、文件路由、数据加载与渲染策略
1,200 周安装