如何在Django Admin中通过自定义按钮切换显示/隐藏credentials字段?
Django Admin 实现自定义按钮切换字段显示/隐藏
问题描述
我有如下Django模型及Admin配置:
class Webhook(models.Model): uuid = models.UUIDField(default=uuid.uuid4, editable=False) url = models.CharField(max_length=256) credentials = models.JSONField(null=True, blank=True, default=dict) @admin.register(models.Webhook) class WebhookAdmin(admin.ModelAdmin): list_display = ("id", "uuid", "url") fields = ("uuid", "url", "toggle_credentials_button", "credentials") readonly_fields = ("uuid", "toggle_credentials_button") def toggle_credentials_button(self, obj): return format_html("""<a class="button">Toggle Credentials</a> """) toggle_credentials_button.allow_tags = True
需求:
- 点击自定义的
Toggle Credentials按钮时,切换credentials字段的显示/隐藏状态 - 默认访问页面时
credentials字段处于隐藏状态 - 显示状态不持久,页面刷新或跳转后需重新点击才能显示
- 仅在Django Admin中实现该功能
实现方案
1. 修正原代码的小问题
toggle_credentials_button.allow_tags在Django 1.9及以上版本已被弃用,推荐使用mark_safe替代(兼容旧版本但更规范)- 给按钮添加自定义类名,方便JavaScript定位;通过DOM结构关联
credentials字段容器
2. 修改WebhookAdmin类
from django.contrib import admin from django.utils.html import format_html from django.utils.safestring import mark_safe import uuid from .models import Webhook # 确保导入你的模型 @admin.register(Webhook) class WebhookAdmin(admin.ModelAdmin): list_display = ("id", "uuid", "url") fields = ("uuid", "url", "toggle_credentials_button", "credentials") readonly_fields = ("uuid", "toggle_credentials_button") def toggle_credentials_button(self, obj): # 添加自定义类名,方便JS选择按钮 return format_html('<a class="button toggle-credentials-btn">Toggle Credentials</a> ') # 替换allow_tags为mark_safe(Django 1.9+推荐写法) toggle_credentials_button.short_description = "操作" toggle_credentials_button = mark_safe(toggle_credentials_button) # 引入自定义JS文件 class Media: js = ('admin/js/toggle_credentials.js',)
3. 创建自定义JavaScript文件
在项目的static/admin/js/目录下创建toggle_credentials.js(目录不存在请手动创建),内容如下:
document.addEventListener('DOMContentLoaded', function() { // 定位切换按钮和credentials字段的容器 const toggleBtn = document.querySelector('.toggle-credentials-btn'); const credentialsField = document.querySelector('div.field-credentials'); // 初始隐藏credentials字段 if (credentialsField) { credentialsField.style.display = 'none'; } // 绑定点击切换事件 if (toggleBtn && credentialsField) { toggleBtn.addEventListener('click', function(e) { e.preventDefault(); // 切换显示/隐藏状态 credentialsField.style.display = credentialsField.style.display === 'none' ? 'block' : 'none'; }); } });
4. 注意事项
- 确保项目已正确配置静态文件(
settings.py中STATIC_URL正常配置,开发环境DEBUG=True时自动处理静态文件加载) - 默认Admin模板会自动加载
Media中声明的JS文件,无需额外修改模板
内容的提问来源于stack exchange,提问作者Ashutosh
相关产品推荐
相关产品推荐

