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

如何覆盖pipe理模板(例如admin / index.html),同时对其进行扩展(请参阅https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing -an-admin-template )?

首先 – 我知道这个问题之前已经被问到和回答过了(请参阅Django:覆盖和扩展应用程序模板 ),但正如答案所示,如果您使用的是app_directories模板加载器(这是大部分时间)。

我目前的解决方法是复制和扩展,而不是直接从pipe理模板扩展。 这个工程很好,但是当pipe理模板改变的时候,它会让人感到困惑,并增加额外的工作。

它可以为模板想一些自定义的扩展标签,但如果已经存在解决scheme,我不想重新发明轮子。

在旁注:有没有人知道Django本身是否会解决这个问题?

大约一年半前,我遇到了同样的问题,我在djangosnippets.org上find了一个很好的模板加载器 ,使得它变得简单。 它允许您在特定的应用程序中扩展模板,使您能够创build自己的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 %} 

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

至于Django 1.8是当前的版本,不需要符号链接,将admin / templates复制到您的项目文件夹,或按照上面的答案build议安装中间件。 这是做什么:

  1. 创build以下树形结构(由官方文档推荐)

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

注意 :这个文件的位置并不重要。 你可以把它放在你的应用程序,它仍然会工作。 只要它的位置可以被django发现。 更重要的是,HTML文件的名称必须与django提供的原始HTML文件名相同。

  1. 将此模板path添加到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,所以对我来说,path是在这里:

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

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

  1. 你的change_form.html中 ,写下这样的东西:

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

如果您需要覆盖admin/index.html ,则可以设置AdminSite的index_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.5(至less),你可以定义你想用于特定模板的模板

请参阅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是一个简单的HTML模板扩展admin/change_form.html (或者如果你想从头开始做)

最好的办法是把Django的pipe理模板放到你的项目中。 所以你的模板将在templates/admin而股票Djangopipe理模板将在说template/django_admin 。 然后,你可以做如下的事情:

模板/pipe理/ change_form.html

 {% extends 'django_admin/change_form.html' %} Your stuff here 

如果你担心保持库存模板是最新的,你可以包含svn外部或类似的。

Chengs的答案是正确的,但根据pipe理员文档,不是每个pipe理模板都可以这样覆盖: 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 

对于那些不能以这种方式重写的模板 ,您可能仍然会覆盖整个项目的模板 。 只需新版本放置在您的模板/pipe理员目录中。 这对创build自定义404和500页面特别有用

我不得不覆盖pipe理员的login.html,因此不得不把覆盖的模板放在这个文件夹结构中:

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

(没有在pipe理员myapp子文件夹)我没有足够的repution评论程的职位,这就是为什么我不得不写这个新的答案。

我同意克里斯普拉特。 但是我认为最好创build符号链接到pipe理模板放在其中的原始Django文件夹:

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

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

这个网站有一个简单的解决scheme,与我的Django 1.7configuration。

首先:在项目的模板/目录中build立一个名为admin_src的符号链接到你安装的Django模板。 对于我使用virtualenv的Dreamhost,我的“源”Djangopipe理模板在:

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

第二:在模板/

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

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

THIRD:在你的新模板/ admin /目录下创build一个包含以下内容的base.html文件:

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

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

完成。 简单。

你可以使用django-overextends ,它为Django提供循环模板的inheritance。

它来自Mezzanine CMS,从Stephen提取它到独立的Django扩展。

您可以在Mezzanine文档中的“覆盖vs扩展模板”(http:/mezzanine.jupo.org/docs/content-architecture.html#overriding-vs-extending-templates)中find更多信息。

有关更深层次的内容,请参阅Stephens博客“Django的循环模板inheritance”(http:/blog.jupo.org/2012/05/17/circular-template-inheritance-for-django)。

在Google Groups中讨论(https:/groups.google.com/forum/#!topic / mezzanine-users / sUydcf_IZKQ),开始开发此function。

注意:

我没有声望添加超过2个链接。 但是我认为这些链接提供了有趣的背景信息。 所以我刚刚在“http(s):”之后留下了一个斜线。 也许有更好的声誉的人可以修复链接并删除这个笔记。