
本文介绍如何在 django admin 的批量删除确认页面(delete_selected_confirmation.html)中,根据业务逻辑动态显示自定义警告消息,而非简单覆盖模板——通过重写 admin action 并注入条件化上下文实现灵活控制。
本文介绍如何在 django admin 的批量删除确认页面(delete_selected_confirmation.html)中,根据业务逻辑动态显示自定义警告消息,而非简单覆盖模板——通过重写 admin action 并注入条件化上下文实现灵活控制。
在 Django Admin 中,默认的「批量删除」功能由内置的 delete_selected action 提供,其确认页面使用 delete_selected_confirmation.html 模板渲染。若需在该页面按条件显示额外警告(如提示关联资源将被级联影响),仅复制并修改模板是不够的——因为模板本身无法访问请求、查询集或业务逻辑。正确做法是:接管该 action 的执行流程,在渲染前动态计算并注入上下文变量。
✅ 推荐方案:自定义 action + 复用原生逻辑
Django 官方不提供类似 render_delete_selected_confirmation() 的钩子方法,因此不能像 render_delete_form() 那样直接覆写。但我们可以安全地复用 django.contrib.admin.actions.delete_selected 函数,并在其返回的 TemplateResponse 中修改 context_data:
传媒企业网站系统使用热腾CMS(RTCMS),根据网站板块定制的栏目,如果修改栏目,需要修改模板相应的标签。站点内容均可在后台网站基本设置中添加。全站可生成HTML,安装默认动态浏览。并可以独立设置SEO标题、关键字、描述信息。源码包中带有少量测试数据,安装时可选择演示安装或全新安装。如果全新安装,后台内容充实后,首页才能完全显示出来。(全新安装后可以删除演示数据用到的图片,目录在https://
# admin.py
from django.contrib import admin
from django.contrib.admin.actions import delete_selected
from django.template.response import TemplateResponse
from django.http import HttpRequest
from django.db.models import QuerySet
from .models import MyModel
@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
actions = ["delete_selected_my_models"]
def get_actions(self, request: HttpRequest) -> dict:
# 移除默认的 delete_selected action,避免冲突
actions = super().get_actions(request)
actions.pop('delete_selected', None)
return actions
def should_show_alarm(self, request: HttpRequest, obj: MyModel) -> bool:
"""自定义业务判断逻辑:例如检查对象是否处于‘激活’状态或存在关联数据"""
return obj.is_active and obj.related_items.exists()
@admin.action(description="删除选中的 MyModel 实例")
def delete_selected_my_models(
self,
request: HttpRequest,
queryset: QuerySet[MyModel]
) -> TemplateResponse:
# 调用原生 delete_selected 获取初始响应
response = delete_selected(self, request, queryset)
# 仅在 GET 请求(即确认页展示阶段)注入上下文;POST 时跳过(进入实际删除)
if not request.POST.get("post"):
show_alarm = False
affected_objects = []
for obj in queryset:
if self.should_show_alarm(request, obj):
show_alarm = True
affected_objects.append(obj)
# 注入自定义上下文变量,供模板使用
response.context_data.update({
"show_alarm": show_alarm,
"affected_objects": affected_objects,
"alarm_message": "⚠️ 注意:以下条目处于激活状态,删除将同步解除关联配置。"
})
return response? 模板适配(templates/admin/myapp/mymodel/delete_selected_confirmation.html)
在自定义模板中,可安全使用注入的变量(注意:需确保路径与 AppConfig.name 和模型名匹配):
{% extends "admin/delete_selected_confirmation.html" %}
{% block content %}
{{ block.super }}
{% if show_alarm %}
<div class="errornote">
<h3>{{ alarm_message }}</h3>
<ul>
{% for obj in affected_objects %}
<li>{{ obj }}(ID: {{ obj.pk }})</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% endblock %}⚠️ 关键注意事项
- 不要直接修改 request.POST 或绕过 CSRF 校验:本方案完全复用 Django 原生删除逻辑,安全性无损。
- 性能考虑:should_show_alarm 中的数据库查询(如 obj.related_items.exists())会在每个对象上调用,若 queryset 较大,建议改用 queryset.filter(...).exists() 批量判断。
-
模板路径必须精确:Django 按 admin/
/ /delete_selected_confirmation.html 查找,否则回退至默认模板。 - get_actions() 是必需的:必须显式移除默认 delete_selected,否则两个同名 action 会冲突或导致不可预期行为。
通过该方式,你获得了完整的上下文控制权——既能复用 Django 经过充分测试的删除流程,又能根据任意业务规则动态呈现用户提示,兼顾扩展性与稳定性。









