问题:如何覆盖和扩展基本的Django管理模板?
How do I override an admin template (e.g. admin/index.html) while at the same time extending it (see https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template)?
First – I know that this question has been asked and answered before (see Django: Overriding AND extending an app template) but as the answer says it isn’t directly applicable if you’re using the app_directories template loader (which is most of the time).
My current workaround is to make copies and extend from them instead of extending directly from the admin templates. This works great but it’s really confusing and adds extra work when the admin templates change.
It could think of some custom extend-tag for the templates but I don’t want to reinvent the wheel if there already exists a solution.
On a side note: Does anybody know if this problem will be addressed by Django itself?
回答 0
回答 1
对于最新版本的Django 1.8,无需进行符号链接,将admin / templates复制到您的项目文件夹中,也无需按照上面的答案建议安装中间件。这是做什么的:
创建以下树结构(官方文档推荐)
your_project
|-- your_project/
|-- myapp/
|-- templates/
|-- admin/
|-- myapp/
|-- change_form.html <- do not misspell this
注意:此文件的位置并不重要。您可以将其放入您的应用程序中,并且仍然可以使用。只要它的位置可以被django发现。更重要的是,HTML文件的名称必须与django提供的原始HTML文件名相同。
将此模板路径添加到您的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',
],
},
},
]
确定名称和要覆盖的块。这是通过查看django的admin / templates目录来完成的。我正在使用virtualenv,因此对我来说,路径在这里:
~/.virtualenvs/edge/lib/python2.7/site-packages/django/contrib/admin/templates/admin
在此示例中,我要修改添加新用户表单。该视图负责的模板是change_form.html。打开change_form.html并找到要扩展的{%block%}。
在您的change_form.html中,编写如下内容:
{% extends "admin/change_form.html" %}
{% block field_sets %}
{# your modification here #}
{% endblock %}
加载您的页面,您应该看到更改
As for Django 1.8 being the current release, there is no need to symlink, copy the admin/templates to your project folder, or install middlewares as suggested by the answers above. Here is what to do:
create the following tree structure(recommended by the official documentation)
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.
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',
],
},
},
]
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.
In your change_form.html, write somethings like this:
{% extends "admin/change_form.html" %}
{% block field_sets %}
{# your modification here #}
{% endblock %}
Load up your page and you should see the changes
回答 2
如果您需要覆盖admin/index.html
,则可以设置的index_template参数AdminSite
。
例如
# 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
if you need to overwrite the admin/index.html
, you can set the index_template parameter of the AdminSite
.
e.g.
# urls.py
...
from django.contrib import admin
admin.site.index_template = 'admin/my_custom_index.html'
admin.autodiscover()
and place your template in <appname>/templates/admin/my_custom_index.html
回答 3
With django
1.5 (at least) you can define the template you want to use for a particular modeladmin
see https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#custom-template-options
You can do something like
class Myadmin(admin.ModelAdmin):
change_form_template = 'change_form.htm'
With change_form.html
being a simple html template extending admin/change_form.html
(or not if you want to do it from scratch)
回答 4
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
对于无法以这种方式覆盖的模板,您仍然可以在整个项目中覆盖它们。只需将新版本放在您的template / admin目录中即可。这对于创建自定义404和500页特别有用
我必须覆盖admin的login.html,因此必须将覆盖的模板放在此文件夹结构中:
your_project
|-- your_project/
|-- myapp/
|-- templates/
|-- admin/
|-- login.html <- do not misspell this
(没有admin中的myapp子文件夹)我没有足够的声誉来评论Cheng的帖子,这就是为什么我不得不将其编写为新答案。
Chengs’s answer is correct, howewer according to the admin docs not every admin template can be overwritten this way: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#overriding-admin-templates
Templates which may be overridden per app or model
Not every template in contrib/admin/templates/admin may be overridden per app or per model. The following can:
app_index.html
change_form.html
change_list.html
delete_confirmation.html
object_history.html
For those templates that cannot be overridden in this way, you may still override them for your entire project. Just place the new version in your templates/admin directory. This is particularly useful to create custom 404 and 500 pages
I had to overwrite the login.html of the admin and therefore had to put the overwritten template in this folder structure:
your_project
|-- your_project/
|-- myapp/
|-- templates/
|-- admin/
|-- login.html <- do not misspell this
(without the myapp subfolder in the admin) I do not have enough repution for commenting on Cheng’s post this is why I had to write this as new answer.
回答 5
最好的方法是将Django管理模板放入您的项目中。因此,您的模板将在其中,templates/admin
而库存的Django管理模板将在其中template/django_admin
。然后,您可以执行以下操作:
templates / admin / change_form.html
{% extends 'django_admin/change_form.html' %}
Your stuff here
如果您担心要使库存模板保持最新状态,则可以在svn外部组件或类似工具中包含它们。
The best way to do it is to put the Django admin templates inside your project. So your templates would be in templates/admin
while the stock Django admin templates would be in say template/django_admin
. Then, you can do something like the following:
templates/admin/change_form.html
{% extends 'django_admin/change_form.html' %}
Your stuff here
If you’re worried about keeping the stock templates up to date, you can include them with svn externals or similar.
回答 6
我找不到官方的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/
这是您需要做的:
在中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
(来自之前的步骤自定义管理应用程序配置)。
在中mysite/urls.py
,admin.site.urls
从管理URL 替换为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的源代码中找到。
现在,您可以通过从头开始编写模板来覆盖模板,也可以对其进行扩展,然后覆盖/扩展特定的块。
例如,如果您想将所有内容保持原样但要覆盖该content
块(在索引页面上列出了您注册的应用及其模型),则将以下内容添加到中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
和extrahead
块来添加自定义样式和脚本。
I couldn’t find a single answer or a section in the official Django docs that had all the information I needed to override/extend the default admin templates, so I’m writing this answer as a complete guide, hoping that it would be helpful for others in the future.
Assuming the standard Django project structure:
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/
Here’s what you need to do:
In mysite/admin.py
, create a sub-class of 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()
Make sure to import custom_admin_site
in the admin.py
of your apps and register your models on it to display them on your customized admin site (if you want to).
In mysite/apps.py
, create a sub-class of AdminConfig
and set default_site
to admin.CustomAdminSite
from the previous step:
from django.contrib.admin.apps import AdminConfig
class CustomAdminConfig(AdminConfig):
default_site = 'admin.CustomAdminSite'
In mysite/settings.py
, replace django.admin.site
in INSTALLED_APPS
with apps.CustomAdminConfig
(your custom admin app config from the previous step).
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)),
...
]
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.
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 %}
To preserve the original contents of a block, add {{ block.super }}
wherever you want the original contents to be displayed:
{% extends 'admin/index.html' %}
{% block content %}
<h1>
Hello, {{ world }}!
</h1>
{{ block.super }}
{% endblock %}
You can also add custom styles and scripts by modifying the extrastyle
and extrahead
blocks.
回答 7
我同意克里斯·普拉特(Chris Pratt)的观点。但我认为最好将符号链接创建到原始Django文件夹,并将其放置在管理模板中:
ln -s /usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/admin/ templates/django_admin
如您所见,它取决于python版本和Django的安装文件夹。因此,将来或在生产服务器上,您可能需要更改路径。
I agree with Chris Pratt. But I think it’s better to create the symlink to original Django folder where the admin templates place in:
ln -s /usr/local/lib/python2.7/dist-packages/django/contrib/admin/templates/admin/ templates/django_admin
and as you can see it depends on python version and the folder where the Django installed. So in future or on a production server you might need to change the path.
回答 8
这个站点有一个与我的Django 1.7配置一起使用的简单解决方案。
首先:在项目的template /目录中,创建一个名为admin_src的符号链接到已安装的Django模板。对我来说,使用virtualenv在Dreamhost上,我的“源” Django管理模板位于:
~/virtualenvs/mydomain/lib/python2.7/site-packages/django/contrib/admin/templates/admin
第二:在模板/中创建管理目录
所以我项目的template /目录现在看起来像这样:
/templates/
admin
admin_src -> [to django source]
base.html
index.html
sitemap.xml
etc...
第三:在新的template / 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文件夹中。
做完了 简单。
This site had a simple solution that worked with my Django 1.7 configuration.
FIRST: Make a symlink named admin_src in your project’s template/ directory to your installed Django templates. For me on Dreamhost using a virtualenv, my “source” Django admin templates were in:
~/virtualenvs/mydomain/lib/python2.7/site-packages/django/contrib/admin/templates/admin
SECOND: Create an admin directory in templates/
So my project’s template/ directory now looked like this:
/templates/
admin
admin_src -> [to django source]
base.html
index.html
sitemap.xml
etc...
THIRD: In your new template/admin/ directory create a base.html file with this content:
{% extends "admin_src/base.html" %}
{% block extrahead %}
<link rel='shortcut icon' href='{{ STATIC_URL }}img/favicon-admin.ico' />
{% endblock %}
FOURTH: Add your admin favicon-admin.ico into your static root img folder.
Done. Easy.
回答 9
对于应用程序索引,将此行添加到某个常见的py文件(例如url.py)中
admin.site.index_template = 'admin/custom_index.html'
对于应用程序模块索引:将此行添加到admin.py
admin.AdminSite.app_index_template = "servers/servers-home.html"
对于更改列表:将此行添加到admin类:
change_list_template = "servers/servers_changelist.html"
对于应用程序模块表单模板:将此行添加到您的管理类中
change_form_template = "servers/server_changeform.html"
等等,并在同一管理员的模块类中查找其他
for app index add this line to somewhere common py file like url.py
admin.site.index_template = 'admin/custom_index.html'
for app module index : add this line to admin.py
admin.AdminSite.app_index_template = "servers/servers-home.html"
for change list : add this line to admin class:
change_list_template = "servers/servers_changelist.html"
for app module form template : add this line to your admin class
change_form_template = "servers/server_changeform.html"
etc. and find other in same admin’s module classes
回答 10
您可以使用django-overextends,它为Django提供了循环模板继承。
它来自Mezzanine CMS,Stephen从中将其提取到独立的Django扩展中。
您可以在夹层文档中的“覆盖与扩展模板”(http:/mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates)中找到更多信息。
有关更深入的信息,请参见Stephens Blog“ Django的循环模板继承”(http:/blog.jupo.org/2012/05/17/circular-template-inheritance-for-django)。
在Google网上论坛中,讨论(https://groups.google.com/forum/#!topic/mezzanine-users/sUydcf_IZkQ)开始了该功能的开发。
注意:
我没有添加两个以上链接的声誉。但是我认为这些链接提供了有趣的背景信息。因此,我在“ http(s):”之后留了一个斜线。也许信誉较高的人可以修复链接并删除此注释。
You can use django-overextends, which provides circular template inheritance for Django.
It comes from the Mezzanine CMS, from where Stephen extracted it into a standalone Django extension.
More infos you find in “Overriding vs Extending Templates” (http:/mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates) inside the Mezzanine docs.
For deeper insides look at Stephens Blog “Circular Template Inheritance for Django” (http:/blog.jupo.org/2012/05/17/circular-template-inheritance-for-django).
And in Google Groups the discussion (https:/groups.google.com/forum/#!topic/mezzanine-users/sUydcf_IZkQ) which started the development of this feature.
Note:
I don’t have the reputation to add more than 2 links. But I think the links provide interesting background information. So I just left out a slash after “http(s):”. Maybe someone with better reputation can repair the links and remove this note.
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。