如何重写和扩展基本的Django管理模板?

172 投票
12 回答
242568 浏览
提问于 2025-04-16 20:52

我想知道怎么在不完全替换的情况下,重写一个管理员模板(比如 admin/index.html),同时又能扩展它(可以参考这个链接:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template)。

首先,我知道这个问题之前有人问过并且得到了回答(可以看这个链接:Django: Overriding AND extending an app template),但是正如答案所说,如果你使用的是 app_directories 模板加载器(这通常是大多数情况下),这个答案就不太适用了。

我现在的解决办法是先复制一份模板,然后从复制的模板扩展,而不是直接从管理员模板扩展。这样做虽然有效,但真的很让人困惑,而且当管理员模板更新时,还得额外处理很多事情。

我可以考虑为模板想一些自定义的扩展标签,但如果已经有现成的解决方案,我就不想重复造轮子了。

顺便问一下,有人知道 Django 会不会解决这个问题吗?

12 个回答

66

如果你需要覆盖 admin/index.html 文件,可以设置 AdminSiteindex_template 参数。

比如说:

# urls.py
...
from django.contrib import admin

admin.site.index_template = 'admin/my_custom_index.html'
admin.autodiscover()

然后把你的模板放在 <appname>/templates/admin/my_custom_index.html 这个位置。

86

关于Django 1.8这个版本,现在不需要像上面回答中提到的那样去创建符号链接、复制admin/templates到你的项目文件夹,或者安装中间件。你只需要按照以下步骤操作:

  1. 创建以下的文件结构(这是官方文档推荐的)

    your_project
         |-- your_project/
         |-- myapp/
         |-- templates/
              |-- admin/
                  |-- myapp/
                      |-- change_form.html  <- do not misspell this
    

注意:这个文件放在哪里并不重要。你可以把它放在你的应用程序里,它依然可以正常工作。只要Django能找到它就行。更重要的是,HTML文件的名字必须和Django提供的原始HTML文件名完全一样。

  1. 在你的settings.py文件中添加这个模板路径:

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')], # <- add this line
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
  2. 确定你想要修改的名称和区块。这可以通过查看Django的admin/templates目录来完成。我使用的是virtualenv,所以我的路径是这里:

    ~/.virtualenvs/edge/lib/python2.7/site-packages/django/contrib/admin/templates/admin
    

在这个例子中,我想修改添加新用户的表单。负责这个视图的模板是change_form.html。打开change_form.html,找到你想要扩展的{% block %}。

  1. 你的change_form.html中,写一些像这样的内容:

    {% extends "admin/change_form.html" %}
    {% block field_sets %}
         {# your modification here #}
    {% endblock %}
    
  2. 加载你的页面,你应该能看到变化

128

更新:

查看你所用Django版本的文档,比如最新版本的文档这里,或者旧的长期支持版本:3.22.21.11

2011年的原始回答:

大约一年半前我也遇到过同样的问题,我在djangosnippets.org上找到一个很不错的模板加载器,它让这件事变得简单。这个加载器允许你在特定的应用中扩展一个模板,这样你就可以创建自己的admin/index.html,并且这个文件可以扩展来自管理应用的admin/index.html模板。像这样:

{% extends "admin:admin/index.html" %}

{% block sidebar %}
    {{block.super}}
    <div>
        <h1>Extra links</h1>
        <a href="/admin/extra/">My extra link</a>
    </div>
{% endblock %}

我在我的博客文章中给出了如何使用这个模板加载器的完整示例。

撰写回答