在Django Admin中为应用名称添加链接的优雅方案
可行替代方案
针对你不想重写整个app_list.html的需求,有以下几种可行方法:
方法一:JavaScript注入(最轻量化,升级友好)
无需修改后端或核心模板,仅需扩展admin的基础模板,通过脚本在页面加载后动态添加链接:
- 在项目的
templates/admin/base_site.html中添加以下内容:
{% extends "admin/base_site.html" %} {% block extrahead %} {{ block.super }} <script> document.addEventListener('DOMContentLoaded', function() { // 遍历所有应用标题,找到APP1 const appTitles = document.querySelectorAll('caption a.section'); appTitles.forEach(title => { if (title.textContent.trim() === 'APP1') { // 创建并插入链接元素 const link = document.createElement('a'); link.href = '/somewhere'; link.textContent = ' 链接'; link.style.marginLeft = '8px'; title.parentNode.appendChild(link); } }); }); </script> {% endblock %}
- 优点:完全不涉及核心模板修改,Django版本升级时几乎无需调整
- 缺点:依赖admin页面的DOM结构,若官方修改了类名或布局,需同步调整脚本
方法二:自定义AdminSite + 局部模板修改
通过扩展AdminSite给APP1添加额外数据,再小范围修改app_list.html:
- 自定义AdminSite并扩展
get_app_list方法:
# 在项目的admin.py中 from django.contrib.admin import AdminSite class CustomAdminSite(AdminSite): def get_app_list(self, request): app_list = super().get_app_list(request) for app in app_list: if app['name'] == 'APP1': # 为APP1添加额外链接信息 app['extra_link'] = {'url': '/somewhere', 'text': '链接'} return app_list # 替换默认admin站点(需将所有模型注册到这个自定义站点) admin_site = CustomAdminSite(name='custom_admin')
- 复制Django内置的
app_list.html到项目templates/admin/目录,仅修改标题渲染行:
原代码:
<a href="{{ app.app_url }}" class="section" title="{% blocktranslate with name=app.name %}Models in the {{ name }} application{% endblocktranslate %}">{{ app.name }}</a>
修改为:
<a href="{{ app.app_url }}" class="section" title="{% blocktranslate with name=app.name %}Models in the {{ name }} application{% endblocktranslate %}">{{ app.name }}</a> {% if app.extra_link %} <a href="{{ app.extra_link.url }}" style="margin-left:8px;">{{ app.extra_link.text }}</a> {% endif %}
- 优点:渲染逻辑更可靠,后端可控
- 缺点:需要复制
app_list.html,但仅修改少量代码,升级时只需对比官方模板的变化同步更新
方法三:自定义模板过滤器
通过模板过滤器封装APP1的链接渲染逻辑,再小范围修改模板:
- 创建模板过滤器:
# 在项目的templatetags/admin_extras.py中 from django import template register = template.Library() @register.filter def app_name_with_link(app): if app.name == 'APP1': return f'{app.name} <a href="/somewhere" style="margin-left:8px;">链接</a>' return app.name
- 复制
app_list.html到项目模板目录,修改标题渲染行:
<a href="{{ app.app_url }}" class="section" title="{% blocktranslate with name=app.name %}Models in the {{ name }} application{% endblocktranslate %}">{{ app|app_name_with_link|safe }}</a>
- 优点:逻辑集中在过滤器,模板修改量极小
- 缺点:同样需要复制
app_list.html,依赖模板结构
内容的提问来源于stack exchange,提问作者James Lin
相关产品推荐
相关产品推荐

