Django Admin 不同层面(简单到复杂)自定义 的示例

明白啦 ✅ 你想要的是:从不同层面(简单到复杂)自定义 Django Admin 的示例,直观展示有哪些扩展方式。下面我分层次给你整理:


1️⃣ 模型级别(ModelAdmin 自定义)

👉 最常见,改模型在后台的展示方式

# admin.py
from django.contrib import admin
from .models import Product

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ("id", "name", "price", "created_at")  # 列表显示字段
    search_fields = ("name",)  # 搜索框
    list_filter = ("category",)  # 过滤器
    ordering = ("-created_at",)  # 默认排序

📌 适合:小改动(显示字段、过滤器、搜索)。


2️⃣ 操作级别(自定义动作)

👉 给列表页加按钮(批量执行任务)

# admin.py
@admin.action(description="批量打折 10%")
def apply_discount(modeladmin, request, queryset):
    for product in queryset:
        product.price *= 0.9
        product.save()

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ("name", "price")
    actions = [apply_discount]

📌 适合:批量操作,如导出、状态修改。


3️⃣ 模板级别(覆盖模板)

👉 修改后台页面样式/布局

目录结构

templates/
 └── admin/
     └── base_site.html

base_site.html

{% extends "admin/base.html" %}
{% block title %}我的管理后台{% endblock %}
{% block branding %}
  <h1 id="site-name">数据平台后台</h1>
{% endblock %}

📌 适合:统一品牌风格(logo、标题)。


4️⃣ 站点级别(AdminSite 自定义)

👉 新建一个后台站点,区分不同角色

from django.contrib.admin import AdminSite

class ProductAdminSite(AdminSite):
    site_header = "产品管理后台"
    site_title = "产品后台"
    index_title = "产品管理"

    def has_permission(self, request):
        return request.user.is_active and request.user.groups.filter(name="产品管理员").exists()

product_admin_site = ProductAdminSite(name="product_admin")

urls.py:

from django.urls import path
from .admin_sites import product_admin_site

urlpatterns = [
    path("product_admin/", product_admin_site.urls),
]

📌 适合:需要多个后台入口(产品后台、运营后台)。


5️⃣ 视图级别(AdminSite 添加自定义页面)

👉 给后台加一个功能页(比如“执行任务”)

from django.urls import path
from django.template.response import TemplateResponse

class MyAdminSite(AdminSite):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path("report/", self.admin_view(self.report_view), name="report"),
        ]
        return my_urls + urls

    def report_view(self, request):
        context = dict(self.each_context(request), report="这里是报表数据")
        return TemplateResponse(request, "admin/report.html", context)

📌 适合:加统计报表、系统任务、工具页面。


6️⃣ 应用级别(AdminConfig)

👉 替换全局后台,更模块化

# myapp/apps.py
from django.contrib.admin.apps import AdminConfig

class CustomAdminConfig(AdminConfig):
    default_site = "myapp.admin.CustomAdminSite"

settings.py:

INSTALLED_APPS = [
    "myapp.apps.CustomAdminConfig",
    ...
]

📌 适合:大项目需要 统一后台风格,并在多个 app 里复用。


🎯 总结

  • ModelAdmin → 列表展示、字段定制
  • Actions → 自定义批量操作
  • Templates → 改 UI、换 logo
  • AdminSite → 多后台、权限隔离
  • 自定义视图 → 报表、工具页
  • AdminConfig → 全局替换后台

要不要我给你画一个 层次金字塔图(从 ModelAdmin → AdminSite → AdminConfig),直观显示“自定义范围越来越大”的关系?

好 👍 我来帮你画一个 完整的 Django Admin 自定义字符图,把所有层次、关系和关键点都罗列出来,涵盖从最基础到高级(包括自定义 view):

┌───────────────────────────────────────┐
│              Django Admin              │
└───────────────────┬───────────────────┘
                    │
   ┌────────────────┴─────────────────┐
   │                                  │
基础配置                           模型展示定制
   │                                  │
   ▼                                  ▼
- 修改站点标题/页脚/LOGO             - list_display
- site_header / site_title            - list_display_links
- index_title                         - list_filter
                                     - search_fields
                                     - ordering
                                     - readonly_fields
                                     - fields / fieldsets


┌───────────────────────────────────────┐
│             表单与字段定制             │
└───────────────────┬───────────────────┘
                    │
                    ▼
- 自定义 ModelForm (form=...)  
- formfield_overrides (全局字段样式)  
- get_form() 动态修改  
- clean_xxx() 校验逻辑  
- raw_id_fields / autocomplete_fields  
- 自定义小部件 widgets  
- Inline (TabularInline / StackedInline) 内联表单  


┌───────────────────────────────────────┐
│             行为逻辑扩展               │
└───────────────────┬───────────────────┘
                    │
                    ▼
- 自定义 action (批量操作按钮)  
- save_model() / delete_model() 钩子  
- get_queryset() 数据范围控制  
- has_add/change/delete/view_permission 权限控制  
- 自定义按钮(changelist_view + extra_context)  


┌───────────────────────────────────────┐
│             界面与前端扩展             │
└───────────────────┬───────────────────┘
                    │
                    ▼
- 重写模板 base_site.html / change_list.html  
- Media(css/js) 注入自定义样式和交互  
- 自定义 AdminSite.index() 改首页布局  
- 使用第三方主题 (django-grappelli, simpleui)  
- dashboard 统计大屏扩展  


┌───────────────────────────────────────┐
│             自定义视图扩展             │
└───────────────────┬───────────────────┘
                    │
      ┌─────────────┴──────────────┐
      │                            │
  ModelAdmin 级别              AdminSite 级别
      │                            │
      ▼                            ▼
- get_urls() 增加子路由          - AdminSite.get_urls() 增加全局路由  
- admin_view() 权限保护          - admin_view() 权限保护  
- 自定义页面 (render/JsonResponse) - 独立页面(如 dashboard、报表)  
- 常见场景:执行任务按钮、导出    - 全局统计、系统配置入口  

📌 总结:

  1. 基础配置 → 修改后台站点的标题、LOGO、首页标题。
  2. 模型展示定制 → 控制列表页、字段显示、搜索、过滤。
  3. 表单与字段定制 → 定制表单行为、字段样式、内联表单。
  4. 行为逻辑扩展 → action、自定义权限、保存/删除逻辑。
  5. 界面与前端扩展 → 模板、样式、Dashboard、美化主题。
  6. 自定义视图扩展 → 在 ModelAdmin / AdminSite 下新增 URL 和自定义页面。

这样整个 Django Admin 的扩展点一览无余。

要不要我帮你把这个字符图配上 最小可运行的代码示例合集(每一层一个示例,拼成一个 Admin 自定义宝典)?

好的 ✅ 我给你整理一个 AdminSite 级别自定义的完整示例
默认情况下我们用的是 django.contrib.admin.site,如果要扩展,就要自己继承 AdminSite


1. 自定义 AdminSite

# myadmin.py
from django.contrib.admin import AdminSite
from django.urls import path
from django.http import HttpResponse
from django.utils.translation import gettext_lazy as _

class MyAdminSite(AdminSite):
    # 基础配置
    site_header = "数据平台管理后台"
    site_title = "数据平台"
    index_title = "欢迎进入数据平台后台"

    # 扩展全局自定义 URL
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path("dashboard/", self.admin_view(self.dashboard_view)),
            path("system-status/", self.admin_view(self.system_status)),
        ]
        return custom_urls + urls

    # 自定义视图1:Dashboard
    def dashboard_view(self, request):
        return HttpResponse("<h1>这是自定义 Dashboard 页面</h1>")

    # 自定义视图2:系统状态
    def system_status(self, request):
        return HttpResponse("系统运行正常 ✅")

2. 在 urls.py 中使用

# urls.py
from django.urls import path, include
from .myadmin import MyAdminSite
from myapp.models import Book
from django.contrib import admin

# 注册模型
my_admin_site = MyAdminSite(name="myadmin")
my_admin_site.register(Book)   # 注册模型到自定义后台

urlpatterns = [
    path("myadmin/", my_admin_site.urls),  # 使用自定义 AdminSite
    path("admin/", admin.site.urls),       # 默认 admin 仍然可用(可选)
]

3. 效果

  • /myadmin/ 进入自定义后台,标题/页脚都改了
  • /myadmin/dashboard/ 访问自定义 Dashboard 页面
  • /myadmin/system-status/ 访问系统状态页面

4. 扩展方向

AdminSite 级别,你可以做的事情比 ModelAdmin 更全局:

  • 全局 Dashboard(例如展示平台指标、统计图表)
  • 全局工具入口(比如“系统配置”、“批量导入数据”)
  • 替代默认 /admin/,做成企业级后台

要不要我给你写一个 自定义 AdminSite Dashboard 页面(带模板 + 图表) 的完整示例?这样更接近实战场景。

明白了 ✅ 我帮你整理一个 AdminSite 级别视图 vs ModelAdmin 级别视图自定义的对比,包括关键点、用途、代码示例和适用场景。


1️⃣ 概念区别

特性AdminSite 级别视图ModelAdmin 级别视图
作用范围整个后台,全局路由某个模型下的子页面或操作
URL 路径/myadmin/...,可独立访问/myadmin/modelname/...,依赖模型上下文
注册方式继承 AdminSiteget_urls()继承 ModelAdminget_urls()
权限控制admin_view() 保护全局权限admin_view() + has_permission()/has_change_permission()
典型用途Dashboard、报表、系统工具、全局配置模型相关操作、批量任务、导出、状态变更
模板渲染自定义模板 + each_context()自定义模板 + extra_context,可继承模型上下文
依赖模型可不依赖任何模型必须依赖一个模型,或模型实例

2️⃣ 代码示例对比

A. AdminSite 级别视图

# myadmin.py
from django.contrib.admin import AdminSite
from django.urls import path
from django.shortcuts import render

class MyAdminSite(AdminSite):
    site_header = "企业后台"
    site_title = "企业管理"
    index_title = "后台首页"

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path("dashboard/", self.admin_view(self.dashboard))
        ]
        return custom_urls + urls

    def dashboard(self, request):
        context = dict(self.each_context(request))
        context['message'] = "欢迎来到后台 Dashboard"
        return render(request, "admin/dashboard.html", context)

# urls.py
my_admin_site = MyAdminSite(name="myadmin")
  • 访问路径/myadmin/dashboard/
  • 特点:全局页面,不依赖模型,可展示全平台统计或系统工具。

B. ModelAdmin 级别视图

from django.contrib import admin
from django.urls import path
from django.shortcuts import render
from .models import Task

class TaskAdmin(admin.ModelAdmin):
    list_display = ("name", "status")

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path("<int:task_id>/run/", self.admin_site.admin_view(self.run_task))
        ]
        return custom_urls + urls

    def run_task(self, request, task_id):
        task = Task.objects.get(id=task_id)
        # 执行自定义逻辑
        context = dict(
            self.admin_site.each_context(request),
            task=task,
            result="任务已执行"
        )
        return render(request, "admin/run_task.html", context)

admin.site.register(Task, TaskAdmin)
  • 访问路径/admin/app/task/123/run/
  • 特点:绑定模型,通常用于操作模型数据或批量操作。

3️⃣ 使用场景总结

层级适合做什么优势局限
AdminSiteDashboard、全局统计、系统管理工具、企业级入口全局控制、可不依赖模型不方便绑定单模型操作
ModelAdmin模型相关操作(批量处理、导出、状态变更)依赖模型上下文,可直接操作模型实例只能在模型下访问,影响范围有限

如果你愿意,我可以帮你画一个 AdminSite vs ModelAdmin 自定义视图的字符图,把两者的关系和路径层次可视化,方便快速理解。

你想要我画吗?

明白了 ✅ 我帮你整理一个 AdminSite 级别视图 vs ModelAdmin 级别视图自定义的对比,包括关键点、用途、代码示例和适用场景。


1️⃣ 概念区别

特性AdminSite 级别视图ModelAdmin 级别视图
作用范围整个后台,全局路由某个模型下的子页面或操作
URL 路径/myadmin/...,可独立访问/myadmin/modelname/...,依赖模型上下文
注册方式继承 AdminSiteget_urls()继承 ModelAdminget_urls()
权限控制admin_view() 保护全局权限admin_view() + has_permission()/has_change_permission()
典型用途Dashboard、报表、系统工具、全局配置模型相关操作、批量任务、导出、状态变更
模板渲染自定义模板 + each_context()自定义模板 + extra_context,可继承模型上下文
依赖模型可不依赖任何模型必须依赖一个模型,或模型实例

2️⃣ 代码示例对比

A. AdminSite 级别视图

# myadmin.py
from django.contrib.admin import AdminSite
from django.urls import path
from django.shortcuts import render

class MyAdminSite(AdminSite):
    site_header = "企业后台"
    site_title = "企业管理"
    index_title = "后台首页"

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path("dashboard/", self.admin_view(self.dashboard))
        ]
        return custom_urls + urls

    def dashboard(self, request):
        context = dict(self.each_context(request))
        context['message'] = "欢迎来到后台 Dashboard"
        return render(request, "admin/dashboard.html", context)

# urls.py
my_admin_site = MyAdminSite(name="myadmin")
  • 访问路径/myadmin/dashboard/
  • 特点:全局页面,不依赖模型,可展示全平台统计或系统工具。

B. ModelAdmin 级别视图

from django.contrib import admin
from django.urls import path
from django.shortcuts import render
from .models import Task

class TaskAdmin(admin.ModelAdmin):
    list_display = ("name", "status")

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path("<int:task_id>/run/", self.admin_site.admin_view(self.run_task))
        ]
        return custom_urls + urls

    def run_task(self, request, task_id):
        task = Task.objects.get(id=task_id)
        # 执行自定义逻辑
        context = dict(
            self.admin_site.each_context(request),
            task=task,
            result="任务已执行"
        )
        return render(request, "admin/run_task.html", context)

admin.site.register(Task, TaskAdmin)
  • 访问路径/admin/app/task/123/run/
  • 特点:绑定模型,通常用于操作模型数据或批量操作。

3️⃣ 使用场景总结

层级适合做什么优势局限
AdminSiteDashboard、全局统计、系统管理工具、企业级入口全局控制、可不依赖模型不方便绑定单模型操作
ModelAdmin模型相关操作(批量处理、导出、状态变更)依赖模型上下文,可直接操作模型实例只能在模型下访问,影响范围有限

如果你愿意,我可以帮你画一个 AdminSite vs ModelAdmin 自定义视图的字符图,把两者的关系和路径层次可视化,方便快速理解。

你想要我画吗?

Scroll to Top