Working with parent and child templates in Django

Introduction

Here I will show you how to working with template inheritance in Django or on other words, working with parent and child templates in Django framework. Being a Python based web framework, Django needs a convenient way to generate HTML dynamically. The most common approach relies on templates. A template contains the static parts of the desired HTML output as well as some special syntax describing how dynamic content will be inserted.

A template is simply a text file. It can generate any text-based format (HTML, XML, CSV, etc.). A template contains variables, which get replaced with values when the template is evaluated, and tags, which control the logic of the template.

The most powerful – and thus the most complex – part of Django’s template engine is template inheritance. Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override.

Prerequisites

Python version – 3.6.5/3.8.5, Django version – 2.2/3.0.8

Project Configuration

You generally create a Django project and under your project you have one or more applications.

Let’s say you have created Django project called myproject and you have also created an app called myapp under myproject. You may check the documentation for creating Django project and apps under project.

I assume you have the required configurations for your myapp in myproject/myproject/settings.py file under INSTALLED_APPS section as below:

INSTALLED_APPS = [
    'myapp.apps.MyappConfig',
	...
]

The myapp.apps.MyappConfig is formed as a dotted notation from myproject/myapp/apps.py, where you will find the class name as MyappConfig that has name myapp.

Templates

It’s easiest to understand template inheritance by starting with an example. A template file is generally an HTML file which you can put the template under your project directory or under your apps directory. If you want to use the project template for your all apps then you can put under project directory. If you want to use separate template for each app then you can put under your app directory.

Here I will put under app directory. Create a directory called templates under myapp. Then again create myapp directory under templates directory.

From Django docs, your project’s TEMPLATES setting describes how Django will load and render templates. The default settings file configures a DjangoTemplates backend whose APP_DIRS option is set to True. By convention DjangoTemplates looks for a templates subdirectory in each of the INSTALLED_APPS section.

From Django docs, now you might be able to get away with putting your templates directly in myapp/templates (rather than creating another myapp subdirectory), but it would actually be a bad idea. Django will choose the first template it finds whose name matches, and if you had a template with the same name in a different application, Django would be unable to distinguish between them. You need to be able to point Django at the right one, and the easiest way to ensure this is by namespacing them. That is, by putting those templates inside another directory named for the application itself.

Let’s create below base template base.html file under myapp/templates/myapp directory:

<!DOCTYPE html>
{% load static %}
<html>
    <head>
        <title>Django - Photo Gallery</title>
        <!-- CSS -->
        <link rel="stylesheet" href="{% static 'css/style.css' %}">
        
        <!-- JAVASCRIPT -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
    </head>
    <body>
	    <div class='container'>
		    <div class="gallery">
                {% block body %}{% endblock body %}
		    </div>
		</div>
        {% block extra_js %}{% endblock extra_js %}
    </body>
</html>

This template, which you’ll call base.html, defines a simple HTML skeleton document that you might use for a simple one-column page. It’s the job of “child” templates to fill the empty blocks with content. Child template may or may not fill the empty blocks. All the block tag does is to tell the template engine that a child template may override those portions of the template.

Create a child template file index.html under myapp/templates/myapp directory. Child template may look like this:

{% extends 'photo/base.html' %}

{% block body %}
       <p>Images</p>
{% endblock body %}

{% block extra_js %}
	<script type='text/javascript'>
		$(document).ready(function() {
			$('.gallery a').simpleLightbox();
		});
	</script>
{% endblock extra_js %}

The extends tag tells the template engine that this template extends another template. When the template system evaluates this template, first it locates the parent – in this case, base.html file.

You can use as many levels of inheritance as needed.

Note that you can’t define multiple block tags with the same name in the same template. This limitation exists because a block tag works in “both” directions. That is, a block tag doesn’t just provide a hole to fill – it also defines the content that fills the hole in the parent. If there were two similarly-named block tags in a template, that template’s parent wouldn’t know which one of the blocks’ content to use.

That’s all. Hope you got an idea on how to create parent and child template files in Django framework.

Leave a Reply

Your email address will not be published. Required fields are marked *