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

时间:2011-07-05 13:59:40

标签: python django django-admin

如何覆盖管理模板(例如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本身是否会解决这个问题吗?

10 个答案:

答案 0 :(得分:96)

更新

阅读您的Django版本的文档。例如

https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#admin-overriding-templates https://docs.djangoproject.com/en/2.0/ref/contrib/admin/#admin-overriding-templates

2011年的原始答案:

大约一年半前我遇到了同样的问题,我找到了一个很好的template loader on djangosnippets.org,这让我很容易。它允许您在特定应用中扩展模板,使您能够创建自己的 admin / index.html ,从admin应用扩展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 %}

我已经在我的网站blog post上提供了有关如何使用此模板加载程序的完整示例。

答案 1 :(得分:43)

如果您需要覆盖admin/index.html,则可以设置AdminSite的{​​{3}}参数。

e.g。

# 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

答案 2 :(得分:13)

使用django 1.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模板(如果您想从头开始,则不行)

答案 3 :(得分:7)

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

  

可根据应用或型号覆盖的模板

     

并非所有contrib / admin / templates / admin中的模板都可以被覆盖   每个应用程序或每个型号。以下内容可以:

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

对于那些无法以这种方式覆盖的模板,您可以   仍然为整个项目覆盖它们。只需放置新的   您的 templates / admin 目录中的版本。这特别有用   创建自定义404和500页

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

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

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

答案 4 :(得分:5)

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

<强>模板/管理/ change_form.html

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

Your stuff here

如果您担心保持库存模板的最新状态,可以将它们包含在svn外部或类似物中。

答案 5 :(得分:1)

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

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

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

答案 6 :(得分:1)

我在Django官方文档中找不到单个答案或包含 all 信息的部分,而这些信息是我覆盖/扩展默认管理模板所需的信息,因此我将这个答案写为完整的指南,希望对以后的其他人有所帮助。

假设标准的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. mysite/settings.py中,将django.admin.site中的INSTALLED_APPS替换为apps.CustomAdminConfig(上一步中的自定义管理应用配置)。

    from django.contrib.admin.apps import AdminConfig
    
    
    class CustomAdminConfig(AdminConfig):
        default_site = 'admin.CustomAdminSite'
    
  4. mysite/urls.py中,将管理URL中的admin.site.urls替换为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. templates目录中创建要修改的模板,并保持docs中指定的默认Django管理模板目录结构。例如,如果您要修改admin/index.html,请创建文件templates/admin/index.html

    所有现有模板都可以通过这种方式进行修改,其名称和结构可以在Django's source code中找到。

  6. 现在,您可以通过从头开始编写模板来覆盖模板,也可以对其进行扩展,然后覆盖/扩展特定的块。

    例如,如果您想保持一切不变,但想覆盖content块(在索引页面上列出了您注册的应用程序及其模型),则将以下内容添加到{{1 }}:

    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 %} extrastyle块来添加自定义样式和脚本。

答案 7 :(得分:0)

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

FIRST:在项目的模板/目录中创建一个名为 admin_src 的符号链接到已安装的Django模板。对于使用virtualenv的Dreamhost,我的“源”Django管理模板位于:

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

SECOND:在templates /

中创建 admin 目录

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

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

THIRD:在新模板/ admin /目录中使用此内容创建 base.html 文件:

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

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

第四:将您的admin favicon-admin.ico添加到静态根目录img文件夹中。

完成。容易。

答案 8 :(得分:0)

您可以使用django-overextends,它为Django提供循环模板继承。

它来自Mezzanine CMS,从那里Stephen将其提取为独立的Django扩展。

您可以在&#34; Overriding vs Extending Templates&#34;中找到更多信息。 (http:/mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates)夹层文档中。

有关更深入的内容,请参阅Stephens博客&#34; Django的循环模板继承&#34; (HTTP:/blog.jupo.org/2012/05/17/circular-template-inheritance-for-django)

在Google网上论坛中,讨论(https:/groups.google.com/forum /#!topic / mezzanine-users / sUydcf_IZkQ)开始开发此功能。

注意:

我不具备添加超过2个链接的声誉。但我认为这些链接提供了有趣的背景信息。所以我在&#34; http(s):&#34;之后省略了一个斜线。也许名声较好的人可以修复链接并删除此注释。

答案 9 :(得分:0)

对于应用程序索引,将此行添加到某个常见的py文件中,例如url.py

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

对于应用程序模块索引:将此行添加到admin.py

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

更改列表:将此行添加到管理类:

change_list_template = "servers/servers_changelist.html"

对于应用程序模块表单模板:将此行添加到您的管理类中

change_form_template = "servers/server_changeform.html"

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