如何覆盖和扩展基本的 Django 管理模板?

如何覆盖管理模板(例如 admin/index.html) ,同时扩展它(参见 https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template) ?

首先-我知道这个问题以前已经被提出和回答过了(参见 Django: 覆盖和扩展应用程序模板) ,但是正如答案所说,如果你使用 app _ directory 模板加载程序(大多数情况下) ,这个问题并不直接适用。

我目前的工作方法是复制并扩展它们,而不是直接从管理模板进行扩展。这个工作非常好,但是当管理模板发生变化时,它真的会让人感到困惑并增加额外的工作量。

它可以为模板提供一些自定义扩展标记,但是如果已经有了解决方案,我不想重新发明轮子。

顺便说一句: 有人知道姜戈自己是否会解决这个问题吗?

221904 次浏览

最好的方法是将 Django 管理模板放在项目中。因此,您的模板将在 templates/admin,而股票 Django 管理模板将在说 template/django_admin。然后,您可以执行以下操作:

Template/admin/change _ form. html

{% extends 'django_admin/change_form.html' %}


Your stuff here

如果您担心股票模板保持最新,您可以将它们包含在 svn 外部或类似的内容中。

更新 :

阅读你的 Django 版本的文档,例如 最新版本或旧的 LTS 版本: 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 %}

我已经给出了一个完整的例子,关于如何使用这个模板加载程序在一个 博客文章在我的网站上。

我同意 Chris Pratt。但我认为最好创建到原始 Django 文件夹的符号链接,管理模板放在这个文件夹中:

ln -s /usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/admin/ templates/django_admin

如您所见,它取决于 python 版本和 Django 安装的文件夹。因此,在将来或在生产服务器上,您可能需要更改路径。

使用 django1.5(至少) ,您可以为特定的 modeladmin定义要使用的模板

https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#custom-template-options

你可以这样做

class Myadmin(admin.ModelAdmin):
change_form_template = 'change_form.htm'

使用 change_form.html作为扩展 admin/change_form.html的简单 html 模板(如果您希望从头开始,也可以不使用它)

如果需要覆盖 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

这个 站点有一个简单的解决方案,可以使用我的 Django 1.7配置。

首先: 在项目的模板/目录中为已安装的 Django 模板创建一个名为 Admin _ src的符号链接。对于我在 Dreamhost 上使用 viralenv,我的“源”Django 管理模板位于:

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

SECOND: 在 template/中创建一个 管理员目录

所以我的项目的模板/目录现在看起来像这样:

/templates/
admin
admin_src -> [to django source]
base.html
index.html
sitemap.xml
etc...

第三个: 在新的模板/admin/目录中创建一个包含以下内容的 Base.html文件:

{% extends "admin_src/base.html" %}


{% block extrahead %}
<link rel='shortcut icon' href='\{\{ STATIC_URL }}img/favicon-admin.ico' />
{% endblock %}

第四: 添加您的管理员收藏夹-admin. ico 到您的静态根 img 文件夹。

好了,小菜一碟。

至于当前版本的 Django 1.8,不需要符号链接,不需要将管理员/模板复制到项目文件夹,也不需要按照上面的答案建议安装中间件。下面是我们应该做的:

  1. 创建以下树结构(由 正式文件推荐)

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

Note: The location of this file is not important. You can put it inside your app and it will still work. As long as its location can be discovered by django. What's more important is the name of the HTML file has to be the same as the original HTML file name provided by django.

  1. Add this template path to your 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. Identify the name and block you want to override. This is done by looking into django's admin/templates directory. I am using virtualenv, so for me, the path is here:

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

In this example, I want to modify the add new user form. The template responsiblve for this view is change_form.html. Open up the change_form.html and find the {% block %} that you want to extend.

  1. In your change_form.html, write somethings like this:

    {% extends "admin/change_form.html" %}
    {% block field_sets %}
    {# your modification here #}
    {% endblock %}
    
  2. Load up your page and you should see the changes

您可以使用 Django 过度伸展,它为 Django 提供循环模板继承。

它来自于 夹层 CMS,Stephen 将它提取到一个独立的 Django 扩展中。

更多信息可以在“重写与扩展模板”( http:/Mezzanine.jupo.org/docs/content-architecture.html#Overriding-vs-Extending-Templates )的夹层文档中找到。

更深层次的内容可以查看 Stephens 博客“ Django 的循环模板继承”( http:/Blog.jupo.org/2012/05/17/Circular-Template-Inheritance-For-Django )。

在谷歌群组中,讨论( https:/Groups.Google.com/forum/#!topic/mezzanine-users/suydcf_izkq )开始了这个功能的开发。

注:

我没有声誉添加超过2个链接。但我认为这些链接提供了有趣的背景信息。所以我在“ http (s) :”后面省略了一个斜杠。也许有人更好的声誉可以修复链接,删除这个说明。

Cheng 的回答是正确的,但是根据管理文档,并不是每个管理模板都可以这样覆盖: Https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#overriding-admin-templates

每个应用程序或模型可能被覆盖的模板

不是贡献/管理/模板/管理中的每个模板都可以被覆盖 每个应用程式或每个型号:

app_index.html
change_form.html
change_list.html
delete_confirmation.html
object_history.html

对于这些 无法重写的模板,你可以 仍然为您的整个项目覆盖它们。只需 地点的新 版本。这是特别有用的 创建自定义404和500页

我必须覆盖管理员的 login.html,因此必须将覆盖的模板放在这个文件夹结构中:

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

(管理员中没有 myapp 子文件夹) 我没有足够的声誉来评论程的帖子,这就是为什么我必须写这个作为新的答案。

For app index 将这一行添加到常见的 py 文件中,如 url.py

admin.site.index_template = 'admin/custom_index.html'

For app module index: 将这一行添加到 admin.py

admin.AdminSite.app_index_template = "servers/servers-home.html"

For change list: 将这一行添加到管理类:

change_list_template = "servers/servers_changelist.html"

对于 app 模块表单模板: 将这一行添加到管理类中

change_form_template = "servers/server_changeform.html"

等,并在同一管理员的模块类中找到其他

我在 Django 官方文档中找不到任何一个答案,也找不到任何一个章节提供了我覆盖/扩展默认管理模板所需的 所有信息,所以我把这个答案作为一个完整的指南来写,希望将来能对其他人有所帮助。

假定 Django 项目的标准结构:

mysite-container/         # project container directory
manage.py
mysite/               # project package
__init__.py
admin.py
apps.py
settings.py
urls.py
wsgi.py
app1/
app2/
...
static/
templates/

你需要做的是:

  1. mysite/admin.py中,创建 AdminSite的一个子类:

    from django.contrib.admin import AdminSite
    
    
    
    
    class CustomAdminSite(AdminSite):
    # set values for `site_header`, `site_title`, `index_title` etc.
    site_header = 'Custom Admin Site'
    ...
    
    
    # extend / override admin views, such as `index()`
    def index(self, request, extra_context=None):
    extra_context = extra_context or {}
    
    
    # do whatever you want to do and save the values in `extra_context`
    extra_context['world'] = 'Earth'
    
    
    return super(CustomAdminSite, self).index(request, extra_context)
    
    
    
    
    custom_admin_site = CustomAdminSite()
    

    确保导入 custom_admin_site到你的应用程序的 admin.py中,并在其上注册你的模型,以便在你自定义的管理站点上显示它们(如果你想的话)。

  2. mysite/apps.py中,创建一个 AdminConfig的子类,并将 default_site从上一步设置为 admin.CustomAdminSite:

    from django.contrib.admin.apps import AdminConfig
    
    
    
    
    class CustomAdminConfig(AdminConfig):
    default_site = 'admin.CustomAdminSite'
    
  3. In mysite/settings.py, replace django.admin.site in INSTALLED_APPS with apps.CustomAdminConfig (your custom admin app config from the previous step).

  4. In mysite/urls.py, replace admin.site.urls from the admin URL to custom_admin_site.urls

    from .admin import custom_admin_site
    
    
    
    
    urlpatterns = [
    ...
    path('admin/', custom_admin_site.urls),
    # for Django 1.x versions: url(r'^admin/', include(custom_admin_site.urls)),
    ...
    ]
    
  5. Create the template you want to modify in your templates directory, maintaining the default Django admin templates directory structure as specified in the docs. For example, if you were modifying admin/index.html, create the file templates/admin/index.html.

    All of the existing templates can be modified this way, and their names and structures can be found in Django's source code.

  6. Now you can either override the template by writing it from scratch or extend it and then override/extend specific blocks.

    For example, if you wanted to keep everything as-is but wanted to override the content block (which on the index page lists the apps and their models that you registered), add the following to templates/admin/index.html:

    {% extends 'admin/index.html' %}
    
    
    {% block content %}
    <h1>
    Hello, \{\{ world }}!
    </h1>
    {% endblock %}
    

    若要保留块的原始内容,请在希望显示原始内容的位置添加 \{\{ block.super }}:

    {% extends 'admin/index.html' %}
    
    
    {% block content %}
    <h1>
    Hello, \{\{ world }}!
    </h1>
    \{\{ block.super }}
    {% endblock %}
    

    还可以通过修改 extrastyleextrahead块添加自定义样式和脚本。