Django: Overriding AND extending an app template

If you want to override a template coming with an app in django (in app/templates/app/) you create a template of the same name in another directory, which the template loader checks before the app's template dir. If you just want to override certain blocks of the template you also have to copy the whole template and change that block, which is actually not very DRY.

Does anybody know a way to override the orginial template, while at the same moment extending it, so that you just have to override the specific block you want to change? (the thing is doing this without changing the template's name, because in some cases you might have to change the view to make it work with another template)

EDIT: As Adam Taylor pointed out in the comments from Django 1.9 on this is possible without any hacks.


Solution 1:

I think the answer from this related question is pertinent; currently, the best solution seems to be to use a custom template loader from the django-apptemplates package on PyPI, so you can just use pip to install it (e.g. pip install django-apptemplates).

The template loader allows you to extend a template in a specific app; for example, to extend the index page of the admin inteface, you would add

'apptemplates.Loader',

to your TEMPLATE_LOADERS list in settings.py, and use

{% extends "admin:admin/index.html" %}

in your templates.

Solution 2:

Django 1.9 and later has this feature:

Django template loaders can now extend templates recursively.

So you can have a file from app1 with contents like this:

app1/templates/example/foobar.html:

<p>I'm from app1</p>
{% block main %}{% endblock %}

And you can extend it with a file from app2 (notice that the template name example/foobar.html is the same):

app2/templates/example/foobar.html:

{% extends "example/foobar.html" %}
{% block main %}
  <p>I'm from app2</p>
{% endblock %}

The end-result should be:

<p>I'm from app1</p>
<p>I'm from app2</p>

Solution 3:

As an update since this seems to be a popular question. I have used the overextends app without any problem. It provides a new keywords overextends that allows to extend templates with the same name.

And it is easy to install with pip:

 pip install -U django-overextends