如何覆盖管理模板(例如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本身是否会解决这个问题吗?
答案 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/
这是您需要做的:
在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
中,并在其上注册模型,以将其显示在自定义的管理网站上(如果需要)。
在mysite/apps.py
中,创建AdminConfig
的子类,并将上一步中的default_site
设置为admin.CustomAdminSite
:
from django.contrib.admin.apps import AdminConfig
class CustomAdminConfig(AdminConfig):
default_site = 'admin.CustomAdminSite'
在mysite/settings.py
中,将django.admin.site
中的INSTALLED_APPS
替换为apps.CustomAdminConfig
(上一步中的自定义管理应用配置)。
from django.contrib.admin.apps import AdminConfig
class CustomAdminConfig(AdminConfig):
default_site = 'admin.CustomAdminSite'
在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)),
...
]
在templates
目录中创建要修改的模板,并保持docs中指定的默认Django管理模板目录结构。例如,如果您要修改admin/index.html
,请创建文件templates/admin/index.html
。
所有现有模板都可以通过这种方式进行修改,其名称和结构可以在Django's source code中找到。
现在,您可以通过从头开始编写模板来覆盖模板,也可以对其进行扩展,然后覆盖/扩展特定的块。
例如,如果您想保持一切不变,但想覆盖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"
等并在同一管理员的模块类中找到其他