How to extend base HTML in Django

Share your love

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:

  1. Maintain a consistent look and feel across all your web application’s web pages.
  2. 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.
  3. 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:

  1. How to create a base template
  2. How to extend a base template
  3. 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:

  1. 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.
  2. 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'],
  3. Inside the project-level templates directory, create a new file called base.html that will serve as your base inheritable template.
  4. 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.

Style your web pages using template inheritance and Bootstrap in Django

How to extend template from another app in Django

Follow these detailed steps to extend a template from another app in Django:

  1. Confirm you have the app registered in the list of INSTALLED_APPS in the settings.py file
  2. Create the child template in another existing app you wish to inherit the template from another app.
  3. 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:

  1. Check the spelling and case sensitivity of the name of the base template.
  2. 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.
  3. Check the path to the base HTML template file is correct.
  4. Ensure you have the right blocks declared in your base HTML template.
  5. Check that your base HTML actually exists in your project directory structure.

Share your love
Badi
Badi

Badi here, creator of ngangasn.com— A website dedicated to providing helpful information and how-to's of web development and hosting. Inspired by a fascination to write the most efficient code to make a computer laugh, & humans, Steve has a passion for organizing characters to create code and informative content.
What makes me happy?
Well, nothing like the feeling of finally figuring out that one pesky bug that's been driving me crazy.

Leave a Reply

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