可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
Update:
Read the Docs for your version of Django. e.g.
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
Original answer from 2011:
I had the same issue about a year and a half ago and I found a nice template loader on djangosnippets.org that makes this easy. It allows you to extend a template in a specific app, giving you the ability to create your own admin/index.html that extends the admin/index.html template from the admin app. Like this:
{% extends \"admin:admin/index.html\" %}
{% block sidebar %}
{{block.super}}
<div>
<h1>Extra links</h1>
<a href=\"/admin/extra/\">My extra link</a>
</div>
{% endblock %}
I\'ve given a full example on how to use this template loader in a blog post on my website.
回答2:
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
回答3:
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
回答4:
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)
回答5:
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.
回答6:
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.
回答7:
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:
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:
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.