How to override and extend basic Django admin templates?
Update:
Read the Docs for your version of Django, e.g. the latest version or old LTS versions: 3.2, 2.2, 1.11
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.
Extend django admin template
change_list.html override file lives in this location:
project/app/templates/admin/app/change_list.html
You almost got it . :)
Also u may use django-debug-toolbar and get the actual templates that were uploaded at the browser side.
Unable to override admin templates in Django 3.0
In order to override the template templates/admin/base_site.html
you have to have the same folder structure in your app.
You have myapp/templates/admin/accounts/base_site.html
, but what you need is myapp/templates/admin/base_site.html. Then it should work.
The order of INSTALLED_APPS
might be also important then.
-> Docs
django override admin template
EDITED PREVIOUS USER RESPONSE -- THIS WORKS:
I think your relative path to the templates directory is wrong.
If you follow these steps it should work: (I tested it myself)
Put the
mytemplates
dir side by side with themanage.py
fileproject
-app1
-app2
-mytemplates
-admin
-base_site.html
-manage.pyChange the TEMPLATE_DIRS to:
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'mytemplates'),)
Make sure the order of the template loader is:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
Override template in django admin
After some tests and research here is the solution.
First, underneath /templates/admin/my_app/my_model/
copy-paste the submit_line.html
from django/contrib/admin/templates/admin/
.
Change submit_line.html
and add any urls you like. Say:
<!-- submit_line.html -->
{% load i18n admin_urls %}
<div class="submit-row">
{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" />{% endif %}
{% if show_delete_link %}
{% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %}
<p class="deletelink-box"><a href="{% add_preserved_filters delete_url %}" class="deletelink">{% trans "Delete" %}</a></p>
{% endif %}
<!-- NEW SUBMIT INPUTS -->
<input type="submit" value="TEST" name="_saveasnewss" />
<input type="submit" value="TEST 2" name="_saveasnews" />
<!-- END NEW SUBMIT INPUTS -->
{% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" />{% endif %}
{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}
{% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" />{% endif %}
</div>
We're copy-pasting it because there aren't any {% block %}
tags inside the change_form.html
to override.
Further on, inside the change_form.html
, add these:
<!-- change_form.html -->
{% extends "admin/change_form.html" %}
{% load my_app_tags %} /* Change "my_app" to your app name that will contain the 'submit_row' template tag */
OTHER OVERRIDES HERE
{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
Finally, in your app's templatetags
, add this template tag:
# my_app/templatetags/my_app_tags.py
from django.contrib.admin.templatetags.admin_modify import submit_row
from django.template.loader import get_template
from django import template
# this would be the path to your "submit_line.html"
t = get_template('admin/my_app/my_model/submit_line.html')
register = template.Library()
register.inclusion_tag(t, takes_context=True)(submit_row)
That's it! Now you should see these extra <input type="submit" />
only under my_model
add/change page. If you want them globally just move submit_line.html
from where it is to templates/admin/
. Don't forget to update the paths inside my_app/templatetags/my_app_tags.py
too.
Django: Extending base.html in django admin
What you are looking is similar to nav-global
.
Try this:
First create a folder in your templates
folder as admin
and create a html file(base_site.html
) in the same folder
Assuming you have separate html file for menu-bars(Let's say the file is nav.html
).
Write the below code in base_site.html
:
{% extends 'admin/base.html' %}
{% block nav-global %}
{% include 'nav.html' %} #Your navigation html file
{% endblock %}
Unrelated to question: I found a git repo which will give you idea how to customize the django-admin menu.
django: how do I actually override admin site template
First open your settings.py and add a template folder:
TEMPLATES = [
{
'DIRS': [
'/path/to/your/django-project/templates', # Absolute Path
# os.path.join(BASE_DIR, 'templates') # Relative Path
],
...
Then move the file base_site.html to the following directory.
It's important to keep the structure on the file system.
/path/to/your/django-project/templates/admin/base_site.html
Content of base_site.html:
{% extends "admin/base_site.html" %}
{% block title %}{{ title }} | {{ site_title|default:_('NEW TITLE') }}{% endblock %}
{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Your new Title</a></h1>
{% endblock %}
{% block nav-global %}{% endblock %}
Django Documentation - Overriding Admin Site
Hope that helps.
Extending Django Admin templates
This should work:
{% extends "admin/change_form.html" %}
{% block field_sets %}
{{ block.super }}
<h1>HELLO</h1>
{% endblock %}
You must call the block from the source change_form.html
template. Do that with {{ block.super }}
as shown above. You can, of course, reverse the order between super
and h1
according to your needs.
Related Topics
Why Is My Pygame Application Loop Not Working Properly
Your CPU Supports Instructions That This Tensorflow Binary Was Not Compiled to Use: Avx Avx2
How to Return Dictionary Keys as a List in Python
How to Redirect 'Print' Output to a File
Plotting Time in Python with Matplotlib
Psycopg2: Insert Multiple Rows with One Query
Nested Defaultdict of Defaultdict
Python: Removing List Element While Iterating Over List
Converting a Pandas Groupby Output from Series to Dataframe
Python Dictionary: Are Keys() and Values() Always the Same Order
Create Own Colormap Using Matplotlib and Plot Color Scale
Get Rows Based on Distinct Values from One Column
Settingwithcopywarning Even When Using .Loc[Row_Indexer,Col_Indexer] = Value
To Read Line from File Without Getting "\N" Appended at the End