How to extend base HTML in Django
Template inheritance is another cool feature that Django provides allowing you to produce consistently-styled web pages across your Django web application.
If you wish to have a unique web design, you can structure one HTML file and use it across all your Django web application’s pages using template inheritance.
The Django template system provides you with template inheritance that allows you to extend base HTML file across your Django templates.
So, how do I extend base HTML in Django?
Use {% extends %} template tag to extend base HTML in your Django templates. After creating your base HTML, you can extend it in other template files using the syntax {% extends 'base.html' %}
where extends
is the keyword to achieve template inheritance and base.html
is the name of the base HTML you’re extending.
What does {% extends ‘base.html’ %} do?
Why extend base HTML in Django?
Here are the reasons why you should extend base HTML in Django:
- Maintain a consistent look and feel across all your web application’s web pages.
- Achieve reusability where you can reuse the header, nav, footer, and other sections of your website code. Thus saving time, increasing your productivity, and making it easy to maintain and update your site.
- Improve site performance by caching templates that have consistent code blocks across your website.
To extend base HTML within your Django templates, follow these detailed steps in the sections:
- How to create a base template
- How to extend a base template
- How to extend a template from another app in Django
How to create a base template
If you want to maintain a great look and feel for your website, you should have a consistent HTML structure and CSS styling that is consistent across all your web pages. To achieve that, you can create a base template, which all other HTML files will extend from.
Here’s how you create a base template in Django:
- Create a project-level templates directory and name it
templates
. You’ll use this directory to store all your extendable HTML files. Use the command,mkdir templates
to create the directory. - Configure Django to look for templates inside the project-level templates directory. In settings.py, and inside the
TEMPLATES
variable, ensure you have the following dictionary key-value pair:"DIRS": [BASE_DIR / 'templates'],
- Inside the project-level templates directory, create a new file called
base.html
that will serve as your base inheritable template. - Inside the
base.html
file, create your unique HTML structure, content, and necessary blocks such as{% block title %}
,{% block content %}
, etc.
Here’s an example base.html
code you can start with. It loads the latest Bootstrap 5 and thus, you can use Bootstrap components and CSS classes to style your pages:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>{% block title %} {% endblock %}</title>
</head>
<body>
{% block nav %}
{% endblock nav %}
{% block content %}
{% endblock content %}
{% block footer %}
<p>Copyright © 2023 mywebsite.com</p>
{% endblock footer %}
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>
Creating a base.html file for your Django project is as easy as that.
Now, let us see how you can extend the base template in your other template files such as index.html, posts_list.html, about.html, etc.
How to extend a base template
After creating your base template and the blocks to be overridden in child templates, you can inherit base.html by following these steps:
Step 1: Create or open the child template that will extend base HTML
You will need to create child templates that will inherit from the base template. You can create app-specific or project-specific child templates.
For app-specific templates, you will need to create them inside the app_name/templates directory. For example, you can create a blog app posts_list.html like this:
# ensure you have app-level templates directory
mkdir blog/templates
# create a child template, posts_list.html
touch blog/posts_list.html
For project-specific templates, you’ll need to create the .html files inside the project-level templates directory. For example, you can create, about.html, contact.html, and index.html files here. Here’s a command to do so:
touch templates/contact.html templates/index.html templates/about.html
Step 2: Add {% extends 'base.html' %}
code at the top of the child template file
After creating and opening the empty child template file, add the following line of template tag code at the top:
{% extends 'base.html' %}
By using the {% extends %}
template tag, you’re instructing Django that the current template is a child template that inherits from the main base HTML.
Step 3: Identify the blocks in your base template
In each parent template, you must create blocks using the {% block block_name %} template tag. These are blocks or sections that can be overridden by child templates to insert customizable data or HTML content and structure.
In our example, I create the {% block content %}
, {% block title %}
, {% block nav %}
, and {% block footer %}
blocks.
Step 4: Fill in the identified blocks in your child template
In your child template, fill in the identified blocks by using the {% block %}
tag. Provide the customized content inside these blocks to replace the contents of the block in the base template.
If you wish to have default content from the base HTML template, do not override them in the child template.
{% extends "base.html" %}
{% block title %}
Welcome to my website
{% endblock %}
{% block nav %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
{% endblock %}
{% block content %}
<div class="jumbotron jumbotron-fluid py-5">
<div class="container">
<h1 class="display-4">Welcome to my website</h1>
<p class="lead">This is the home page of my website.</p>
</div>
</div>
{% endblock %}
Step 5: Create views to render your child template
Now that you have a unique child template, create a view for it so that users can be able to access it using a URL endpoint.
Here’s an example view for the index.html
file:
from django.shortcuts import render
def home_view(request):
return render(request, 'index.html')
Create the URL pattern that links to your home_page view:
from django.urls import path
from .views import home_page
urlpatterns = [
path('', home_page, name='home_page'),
]
Access the home page and voila, you have a very beautiful home page that extends from base HTML.
How to extend template from another app in Django
Follow these detailed steps to extend a template from another app in Django:
- Confirm you have the app registered in the list of
INSTALLED_APPS
in the settings.py file - Create the child template in another existing app you wish to inherit the template from another app.
- Use the {% extends ‘app_name/templates/template_name.html’ %} template tag in your child template
Here is an example of extending a template (form.html) from the contact app to another app template file (feedback_form.html) of the blog app in Django.
Ensure the app you want to extend the template from is registered in the list of installed apps:
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# app registered here
"contact",
"blog",
]
Create or open the child template you wish to inherit to:
code blog/templates/feedback_form.html
Add the {% extends %} template tag in your child template providing the path to the parent template, form.html, of the contact app.
{% extends "contact/templates/form.html" %}
{% block form %}
<!-- Your form content goes here -->
{% endblock %}
Simple as that, mate!
Can I extend two HTML templates in Django?
In one template file, you cannot extend multiple parent HTML templates. Thus, you cannot have more than one {% extends %} template tags in one Django template.
However, you can extend base HTML in multiple HTML templates of your Django web application. When you configure Django project-level templates, you can create a base.html file that you can use in any of your app’s and project’s .html files.
Troubleshoot extends base.html not working
If you are having trouble getting the {% extends 'base.html' %}
tag to work in your Django templates, here are some ways you can attempt to fix the issue:
- Check the spelling and case sensitivity of the name of the base template.
- Make sure you’re using the right extends template tag. It should be
{% extends %}
and not {% extend %}. Note the ‘s’. extends ends with an inflection. - Check the path to the base HTML template file is correct.
- Ensure you have the right blocks declared in your base HTML template.
- Check that your base HTML actually exists in your project directory structure.