2016-06-04 18:50:45 +00:00
|
|
|
====================
|
|
|
|
Overriding templates
|
|
|
|
====================
|
|
|
|
|
|
|
|
In your project, you might want to override a template in another Django
|
|
|
|
application, whether it be a third-party application or a contrib application
|
|
|
|
such as ``django.contrib.admin``. You can either put template overrides in your
|
|
|
|
project's templates directory or in an application's templates directory.
|
|
|
|
|
|
|
|
If you have app and project templates directories that both contain overrides,
|
|
|
|
the default Django template loader will try to load the template from the
|
|
|
|
project-level directory first. In other words, :setting:`DIRS <TEMPLATES-DIRS>`
|
|
|
|
is searched before :setting:`APP_DIRS <TEMPLATES-APP_DIRS>`.
|
|
|
|
|
2018-09-11 19:14:53 +00:00
|
|
|
.. seealso::
|
|
|
|
|
|
|
|
Read :ref:`overriding-built-in-widget-templates` if you're looking to
|
|
|
|
do that.
|
|
|
|
|
2016-06-04 18:50:45 +00:00
|
|
|
Overriding from the project's templates directory
|
|
|
|
=================================================
|
|
|
|
|
|
|
|
First, we'll explore overriding templates by creating replacement templates in
|
|
|
|
your project's templates directory.
|
|
|
|
|
|
|
|
Let's say you're trying to override the templates for a third-party application
|
|
|
|
called ``blog``, which provides the templates ``blog/post.html`` and
|
|
|
|
``blog/list.html``. The relevant settings for your project would look like::
|
|
|
|
|
2019-11-07 10:11:27 +00:00
|
|
|
from pathlib import Path
|
2016-06-04 18:50:45 +00:00
|
|
|
|
2020-08-28 03:57:36 +00:00
|
|
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
2016-06-04 18:50:45 +00:00
|
|
|
|
|
|
|
INSTALLED_APPS = [
|
|
|
|
...,
|
|
|
|
'blog',
|
|
|
|
...,
|
|
|
|
]
|
|
|
|
|
|
|
|
TEMPLATES = [
|
|
|
|
{
|
|
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
2019-11-07 10:11:27 +00:00
|
|
|
'DIRS': [BASE_DIR / 'templates'],
|
2016-06-04 18:50:45 +00:00
|
|
|
'APP_DIRS': True,
|
|
|
|
...
|
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
The :setting:`TEMPLATES` setting and ``BASE_DIR`` will already exist if you
|
|
|
|
created your project using the default project template. The setting that needs
|
|
|
|
to be modified is :setting:`DIRS<TEMPLATES-DIRS>`.
|
|
|
|
|
|
|
|
These settings assume you have a ``templates`` directory in the root of your
|
|
|
|
project. To override the templates for the ``blog`` app, create a folder
|
|
|
|
in the ``templates`` directory, and add the template files to that folder:
|
|
|
|
|
|
|
|
.. code-block:: none
|
|
|
|
|
|
|
|
templates/
|
|
|
|
blog/
|
|
|
|
list.html
|
|
|
|
post.html
|
|
|
|
|
|
|
|
The template loader first looks for templates in the ``DIRS`` directory. When
|
|
|
|
the views in the ``blog`` app ask for the ``blog/post.html`` and
|
|
|
|
``blog/list.html`` templates, the loader will return the files you just created.
|
|
|
|
|
|
|
|
Overriding from an app's template directory
|
|
|
|
===========================================
|
|
|
|
|
|
|
|
Since you're overriding templates located outside of one of your project's
|
|
|
|
apps, it's more common to use the first method and put template overrides in a
|
|
|
|
project's templates folder. If you prefer, however, it's also possible to put
|
|
|
|
the overrides in an app's template directory.
|
|
|
|
|
|
|
|
First, make sure your template settings are checking inside app directories::
|
|
|
|
|
|
|
|
TEMPLATES = [
|
|
|
|
{
|
|
|
|
...,
|
|
|
|
'APP_DIRS': True,
|
|
|
|
...
|
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
If you want to put the template overrides in an app called ``myapp`` and the
|
|
|
|
templates to override are named ``blog/list.html`` and ``blog/post.html``,
|
|
|
|
then your directory structure will look like:
|
|
|
|
|
|
|
|
.. code-block:: none
|
|
|
|
|
|
|
|
myapp/
|
|
|
|
templates/
|
|
|
|
blog/
|
|
|
|
list.html
|
|
|
|
post.html
|
|
|
|
|
|
|
|
With :setting:`APP_DIRS<TEMPLATES-APP_DIRS>` set to ``True``, the template
|
|
|
|
loader will look in the app's templates directory and find the templates.
|
2020-06-23 05:57:19 +00:00
|
|
|
|
|
|
|
.. _extending_an_overridden_template:
|
|
|
|
|
|
|
|
Extending an overridden template
|
|
|
|
================================
|
|
|
|
|
|
|
|
With your template loaders configured, you can extend a template using the
|
|
|
|
:ttag:`{% extends %}<extends>` template tag whilst at the same time overriding
|
|
|
|
it. This can allow you to make small customizations without needing to
|
|
|
|
reimplement the entire template.
|
|
|
|
|
|
|
|
For example, you can use this technique to add a custom logo to the
|
|
|
|
``admin/base_site.html`` template:
|
|
|
|
|
|
|
|
.. code-block:: html+django
|
|
|
|
:caption: templates/admin/base_site.html
|
|
|
|
|
|
|
|
{% extends "admin/base_site.html" %}
|
|
|
|
|
|
|
|
{% block branding %}
|
|
|
|
<img src="link/to/logo.png" alt="logo">
|
|
|
|
{{ block.super }}
|
|
|
|
{% endblock %}
|
|
|
|
|
|
|
|
Key points to note:
|
|
|
|
|
|
|
|
* The example creates a file at ``templates/admin/base_site.html`` that uses
|
|
|
|
the configured project-level ``templates`` directory to override
|
|
|
|
``admin/base_site.html``.
|
|
|
|
* The new template extends ``admin/base_site.html``, which is the same template
|
|
|
|
as is being overridden.
|
|
|
|
* The template replaces just the ``branding`` block, adding a custom logo, and
|
|
|
|
using ``block.super`` to retain the prior content.
|
|
|
|
* The rest of the template is inherited unchanged from
|
|
|
|
``admin/base_site.html``.
|
|
|
|
|
|
|
|
This technique works because the template loader does not consider the already
|
|
|
|
loaded override template (at ``templates/admin/base_site.html``) when
|
|
|
|
resolving the ``extends`` tag. Combined with ``block.super`` it is a powerful
|
|
|
|
technique to make small customizations.
|