用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Mte90/dotfiles --skill django-unfold命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | django-unfold |
| description | Modern Django admin theme - Unfold - customization, settings, components, actions, filters, integrations |
| metadata | {"author":"mte90","version":"1.1.0","based_on":"https://github.com/unfoldadmin/django-unfold","tags":["python","django","admin","unfold","theme","dashboard"]} |
Modern Django admin theme with beautiful design and advanced features.
Unfold is a modern theme for Django admin that provides:
Versions: django-unfold 0.76.x + Django 6.0 fully compatible.
pip install django-unfold
# Or with specific version
pip install django-unfold==0.9.0
# settings.py
INSTALLED_APPS = [
'unfold', # Must come BEFORE django.contrib.admin
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
# ... other apps
]
# Unfold settings
UNFOLD = {
# Configuration here
}
Important:
unfoldmust be first inINSTALLED_APPSto override Django templates.
# settings.py
INSTALLED_APPS = [
'unfold',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
]
# Optional: Add your custom admin site class
# UNFOLD_ADMIN_SITE_CLASS = 'path.to.CustomAdminSite'
Unfold doesn't require changes to your URL configuration:
# urls.py - No changes needed!
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# ... other urls
]
UNFOLD = {
'SITE_HEADER': 'My Company Admin',
'SITE_TITLE': 'My Admin',
'INDEX_TITLE': 'Welcome to Dashboard',
# Or with HTML support
'SITE_HEADER': '<div class="flex items-center gap-2"><span>🚀</span> My Company</div>',
}
UNFOLD = {
'COLORS': {
'primary': {
'50': '239 246 255',
'100': '219 234 254',
'200': '191 219 254',
'300': '147 197 253',
'400': '96 165 250',
'500': '59 130 246',
'600': '37 99 235',
'700': '29 78 216',
'800': '30 64 175',
'900': '30 58 138',
'950': '30 58 138',
},
},
'DARK_MODE_COLORS': {
'primary': {
'50': '239 246 255',
# ... dark mode colors
},
},
}
UNFOLD = {
'SIDEBAR': {
'show_search': True,
'navigation': [
{
'title': 'Main',
'items': [
{'title': 'Dashboard', 'icon': 'dashboard', 'link': '/admin/'},
{'title': 'Users', 'icon': 'people', 'link': '/admin/auth/user/'},
],
},
{
'title': 'Content',
'items': [
{'title': 'Articles', 'icon': 'article', 'link': '/admin/myapp/article/'},
],
},
],
},
}
UNFOLD = {
'DASHBOARD_WIDGETS': [
'unfold.widgets.DashboardStatistics',
'unfold.widgets.DashboardActions',
# Custom widgets
],
}
UNFOLD = {
# Show/hide features
'SHOW_HISTORY': True,
'SHOW_VIEW_ON_SITE': True,
# Disable specific features
'AUTH_PASSWORD_VALIDATION': True,
}
# admin.py
from unfold.admin import ModelAdmin, UnfoldAdminSite
from django.contrib.admin import AdminSite
class CustomAdminSite(UnfoldAdminSite):
site_header = 'My Custom Admin'
site_title = 'My Admin Panel'
index_title = 'Welcome to Management'
def each_context(self, request):
context = super().each_context(request)
# Add custom context
context['custom_data'] = 'value'
return context
admin_site = CustomAdminSite(name='myadmin')
# settings.py
UNFOLD_ADMIN_SITE_CLASS = 'myapp.admin.CustomAdminSite'
# admin.py
from django.contrib import admin
from unfold.admin import ModelAdmin
from .models import Article
@admin.register(Article, site=custom_admin_site)
class ArticleAdmin(ModelAdmin):
list_display = ['title', 'status', 'created_at']
search_fields = ['title', 'content']
list_filter = ['status', 'created_at']
# Unfold-specific
sidebar_fieldsets = (
(None, {'fields': ('title', 'slug')}),
('Content', {'fields': ('content', 'excerpt')}),
)
from unfold.decorators import action
from unfold.actions import Actions
class ArticleAdmin(ModelAdmin):
@action(description='Publish selected')
def make_published(self, request, queryset):
queryset.update(status='published')
@action(description='Export to CSV')
def export_csv(self, request, queryset):
# Export logic
pass
from unfold.decorators import display
class UserAdmin(ModelAdmin):
@display(description="Status", boolean=True)
def is_active(self, obj):
return obj.is_active
@display(description="Actions", order="username")
def user_actions(self, obj):
return f"{obj.first_name} {obj.last_name}"
# In change_view.html or custom template
{% load unfold %}
{% component "card" title="Statistics" %}
<div class="p-4">
<p class="text-2xl font-bold">1,234</p>
<p class="text-gray-500">Total Users</p>
</div>
{% endcomponent %}
# Using Unfold chart component
{% component "chart" type="line" data=chart_data %}
{% endcomponent %}
# In list_display
class UserAdmin(ModelAdmin):
list_display = ['username', 'email', 'status_badge']
@bind_to(admin_order_field='is_active')
def status_badge(self, obj):
from unfold.helpers import icon
if obj.is_active:
return icon('check_circle', classes='text-green-500')
return icon('x_circle', classes='text-red-500')
from unfold import fields
from unfold.forms import ModelForm
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = '__all__'
author = fields.AutocompleteField(
queryset=User.objects.all(),
search_fields=['username', 'email'],
label='Author'
)
from unfold.fields import JSONField
class ConfigAdmin(ModelAdmin):
fieldsets = (
(None, {
'fields': ('config_json',)
}),
)
def get_form(self, request, obj=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
form.base_fields['config_json'] = fields.JSONField(
widget=forms.Textarea(attrs={
'class': 'font-mono text-sm',
'rows': 10
})
)
return form
import unfold.filters as filters
class ArticleAdmin(ModelAdmin):
list_filter = [
('status', filters.DropdownFilter),
('category', filters.DropdownFilter),
('created_at', filters.DateRangeFilter),
('author', filters.AutocompleteFilter),
]
# Dropdown filter
('status', filters.DropdownFilter)
# Date range filter
('created_at', filters.DateRangeFilter)
# Autocomplete filter (for FK/M2M with many items)
('author', filters.AutocompleteFilter)
# Checkbox/radio filter
('is_published', filters.CheckboxFilter)
# Numeric range filter
('views', filters.NumericFilter)
# Text search filter
('title', filters.TextFilter)
from django.http import HttpResponse
from django.shortcuts import render
import csv
import io
class ArticleAdmin(ModelAdmin):
@action(description='Export selected to CSV')
def export_csv(self, request, queryset):
# Create CSV
buffer = io.StringIO()
writer = csv.writer(buffer)
writer.writerow(['Title', 'Status', 'Created'])
for obj in queryset:
writer.writerow([obj.title, obj.status, obj.created])
# Return response
response = HttpResponse(buffer.getvalue(), content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="articles.csv"'
return response
@action(description='Send to publication')
def publish(self, request, queryset):
queryset.update(status='published', published_at=timezone.now())
publish.short_description = 'Publish selected articles'
class ArticleAdmin(ModelAdmin):
def get_row_actions(self, obj):
actions = super().get_row_actions(obj)
actions.append(
actions.Link(
'preview',
icon='visibility',
link=f'/admin/myapp/article/{obj.pk}/preview/'
)
)
return actions
class ArticleAdmin(ModelAdmin):
tabs = [
{'title': 'Content', 'id': 'content'},
{'title': 'SEO', 'id': 'seo'},
{'title': 'Metadata', 'id': 'metadata'},
]
fieldsets = (
(None, {
'fields': ('title', 'content'),
'tab_id': 'content',
}),
('SEO Settings', {
'fields': ('meta_title', 'meta_description'),
'tab_id': 'seo',
}),
('Metadata', {
'fields': ('created_at', 'updated_at'),
'tab_id': 'metadata',
}),
)
# Install
pip install django-guardian
# Add to INSTALLED_APPS
INSTALLED_APPS = [
'guardian',
'unfold',
'django.contrib.admin',
# ...
]
# Add to URLs
from django.contrib import admin
from unfold.contrib.guardian.admin import GuardedModelAdmin
class ArticleAdmin(GuardedModelAdmin):
pass
pip install django-import-export
# Works automatically with Unfold
# Custom resource if needed
from import_export import resources
from unfold.admin import ImportExportMixin
class ArticleResource(resources.ModelResource):
class Meta:
model = Article
fields = ('id', 'title', 'status', 'created_at')
class ArticleAdmin(ImportExportMixin, ModelAdmin):
resource_classes = [ArticleResource]
# Install
pip install django-celery-beat
# Configuration is automatic with Unfold
# Shows schedule in admin dashboard
pip install django-constance[database]
INSTALLED_APPS = [
'constance',
'unfold',
# ...
]
# Configuration is automatic
# Shows in admin under "Constance" section
# Custom form for Unfold login
from django import forms
from unfold.forms import LoginForm
class CustomLoginForm(LoginForm):
def clean(self):
# Add custom validation
cleaned_data = super().clean()
# Custom logic
return cleaned_data
# settings.py
UNFOLD = {
'LOGIN': {
'form': 'myapp.forms.CustomLoginForm',
},
}
# Custom password reset
UNFOLD = {
'PASSWORD_CHANGE_FORM': 'myapp.forms.CustomPasswordChangeForm',
'PASSWORD_RESET_FORM': 'myapp.forms.CustomPasswordResetForm',
}
Unfold automatically supports dark mode based on system preference.
# Force dark mode
UNFOLD = {
'THEME': 'dark', # 'dark' or 'light' or None (auto)
}
UNFOLD = {
'DARK_MODE_COLORS': {
'primary': {
'50': '224 242 254',
'100': '214 238 253',
# ... custom dark mode colors
},
},
}
# settings.py
UNFOLD = {
'STYLES': [
'css/custom.css',
],
}
# templates/admin/base.html
{% extends "admin/base.html" %}
{% load static %}
{% block extrastyle %}
<link rel="stylesheet" href="{% static 'css/custom.css' %}">
{% endblock %}
UNFOLD = {
'SCRIPTS': [
'js/custom.js',
],
}
django-unfold-modalReplaces Django admin's popup windows for related objects (ForeignKey, ManyToMany, etc.) with Unfold-styled modals, so related-object selection happens in-page instead of in separate browser windows.
Key features:
raw_id_fields lookup, autocomplete_fields/Select2, related fields inside inlines)default/large/full) and optional manual resize handlepip install django-unfold-modal
django-unfold-markdownMarkdown editor widget for the Django Unfold admin: a plain-text monospace editor with live preview that renders stored content as Markdown.
Key features:
markdown or mistunepip install django-unfold-markdown
django-unfold-extradjango-unfold>=0.92, django-cms>=5.0,<5.1, django-parler~=2.3)Unofficial "extra" package that enhances the Django Unfold admin interface with Unfold-styled integrations for Django CMS 5.0, django-parler multilingual models, and django-versatileimagefield.
Key features:
PageUser/PageUserGroup/GlobalPagePermission admin with permission inlines, djangocms-versioning adminUnfoldCMSPluginBase with UnfoldStackedInline/UnfoldTabularInline; drop-in Unfold-styled djangocms-link Link plugin and djangocms-alias adminUnfoldTranslatableAdminMixin, UnfoldTranslatableStackedAdminMixin, UnfoldTranslatableTabularAdminMixin, translatable inlinespip install django-unfold-extra
Note: Used in production but the author notes to "expect additional implementation work"; recommended mainly when most CMS plugins are custom-built.
django-admin-action-formsdjango>=3.2)Django admin extension that adds confirmation pages for admin actions: each action can have a custom form shown on an intermediate page before execution, with the form data passed to the action as an extra argument. Works with the stock Django admin (not Unfold-specific, but pairs well with Unfold's admin theming).
Key features:
@action_with_form decorator + ActionForm base class; form data passed to the action as an additional argumentfields/fieldsets, filter_horizontal/filter_vertical, autocomplete_fields, custom widgets and validatorsStackedAdminActionInline, TabularAdminActionInline)django-no-queryset-admin-actionspip install django-admin-action-forms
Add 'django_admin_action_forms' to INSTALLED_APPS.