Generate the master or base template in an app in Django

Video thumbnail

With our static files like Bootstrap configured, the next thing you'll want to do is structure the templates, but, we must do it in an organized way, and that's why master templates are essential.

Creating a master template in Django (or base template) is one of those steps that makes the difference between a project that's easily maintained and one that turns into a chaos of duplicated HTML files.

In my case, at first I only had two views: one for product listing and one for detail. Everything seemed fine until I wanted to add a simple logo and a CSS file. I had to modify both templates... and I realized that, if the application grew, that would be unsustainable.

How to create a master template in Django step by step

Creating a master template in Django (or base template) is one of those steps that makes the difference between a project that's easily maintained and one that turns into a chaos of duplicated HTML files.

In my case, at first I only had two views: one for product listing and one for detail. Everything seemed fine until I wanted to add a simple logo and a CSS file. I had to modify both templates... and I realized that, if the application grew, that would be unsustainable.

The solution was clear: a base template that all others inherited from.

What a master template in Django is and what it's for

A master template (or base template) is an HTML file that defines the main structure of your site: the header, menus, footer, and the blocks where the dynamic content will go.

In Django, it's created by combining the power of the {% block %} and {% extends %} tags. This way, all pages share the same skeleton and only specific fragments change.

Conceptual example:

<!DOCTYPE html>
<html lang="es">
<head>
 <meta charset="UTF-8">
 <title>{% block title %}{% endblock title %}</title>
</head>
<body>
 {% block content %}{% endblock content %}
</body>
</html>

This way, your other views only need to "extend" this base file and define their own content.

⚙️ Why use a base template in your Django projects

When I started working with Django, I found myself repeating the same head, body, and footer in every template. It didn't bother me at first, but as soon as I added a logo, a CSS, and a menu, maintaining consistency became a headache.

That's when I understood the value of master templates:

  • They avoid code duplication: you define the skeleton only once.
  • They improve maintainability: you change something in base.html and it updates in all views.
  • They allow easy scaling: ideal if your app grows to 10 or 100 pages.
  • They increase visual consistency: the user perceives a uniform interface.

️ How to create a Django master template (base.html)

Generating a base view for our app is a FUNDAMENTAL process and the next natural step as the application grows, and this is to ensure that our applications are maintainable and more easily scalable, since it assumes in our case that we have a couple of views, the index for the listing, and the detail of a product for the show, we have something like the following:

<!DOCTYPE html>
<html lang="es">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>
Listado Productos
   </title>
</head>
<body>
<h1>Hola Mundo</h1>
{% for p in products %}
   <h3>{{ p.title }}</h3>
   <a href="{% url 'gestion:show' p.id %}">Ver</a>
{% endfor %}

<nav>
   {% if products.has_previous  %}
       <a href="?page={{ products.previous_page_number }}">Prev</a>
   {% endif %}
   {% for i in products.paginator.page_range %}
       <a href="?page={{ i }}">{{i }}</a>
   {% endfor %}
       {% if products.has_next  %}
       <a href="?page={{ products.next_page_number }}">Next</a>
   {% endif %}
   
</nav>
   
</body>
</html>

And the detail one:

<!DOCTYPE html>
<html lang="es">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>
{{product.title}}
   </title>
</head>
<body>
<h1>{{product.title}}</h1>
   <p>{{product.price}}$</p>
   <p>{{product.category.title}}</p>
   <p>{{product.description}}</p>
</nav>
</body>
</html>

As you can see, the body or HTML skeleton is repeated in both, and the only thing that changes is the content we display in the middle.

So, what happens if you want to add a CSS, JS file, or any other HTML element that requires modifying each of these views; for example, a logo; you would have to modify each of these views, in this case it's simple, since there are only 2 templates in our Django app, but what if your application consists of 10 pages, or 100... the problem grows.

Or if we want to add a navigation menu, footer, or any other component.

Generate base or master view in Django

In these cases, the best option is to create a base view or template for your application, which can be more than one or as many as you need; in this case, we only need one; we create a view:

<!DOCTYPE html>
<html lang="es">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>
   {% block title %}
   
   {% endblock title %}
   </title>
</head>
<body>
   {% block  content %}
   
   {% endblock  %}
</body>
</html>

We create the base.html file inside templates/

Basic structure of base.html

As you can see, this is where we have the base body, the HTML tag, body... and the blocks enclose the dynamic part, you can place as many blocks as you want, in this case we have two, for the body, where we place our detail view or the listing... and the title; each block must have a name, which is the ID.

Use of the {% block title %} and {% block content %} blocks

Each view that inherits from base.html can redefine these blocks as needed.

{% extends "base.html" %}
{% block title %}Listado de Productos{% endblock title %}
{% block content %}
<h2>Productos</h2>
{% for p in products %}
 <h3>{{ p.title }}</h3>
 <a href="{% url 'gestion:show' p.id %}">Ver</a>
{% endfor %}
{% endblock content %}

By just adding {% extends "base.html" %}, you'll see a drastic reduction in duplicated code.

How to inherit the master template in other views: Add header, footer, and static files

With {% load static %} you can incorporate your CSS or JS files into base.html.
For example:

<link rel="stylesheet" href="{% static 'css/style.css' %}">
<script src="{% static 'js/main.js' %}"></script>

Thus, all templates that inherit from the base will automatically have those resources loaded.

Modify your listing, show... and any other templates in your Django app

Now, what we need to do is indicate to our templates that we want them to use the previous base template, to extend or inherit from this previous view; for that:

{% extends "base.html" %}

In this master template we define two blocks, one called content and another title; with these we can place any kind of content where we inherit said template from; as we will do below.

Adapt the detail template

{% extends "base.html" %}
{% block title %}
   {{product.title}}
{% endblock title %}
{% block content %}
<h1>{{product.title}}</h1>
   <p>{{product.price}}$</p>
   <p>{{product.category.title}}</p>
   <p>{{product.description}}</p>
   
{% endblock %}

Adapt the listing template

{% extends "base.html" %}
{% block title %}
Listado Productos
{% endblock title %}
{% block content %}
<h1>Hola Mundo</h1>
{% for p in products %}
   <h3>{{ p.title }}</h3>
   <a href="{% url 'gestion:show' p.id %}">Ver</a>
{% endfor %}

<nav>
   {% if products.has_previous  %}
       <a href="?page={{ products.previous_page_number }}">Prev</a>
   {% endif %}
   {% for i in products.paginator.page_range %}
       <a href="?page={{ i }}">{{i }}</a>
   {% endfor %}
       {% if products.has_next  %}
       <a href="?page={{ products.next_page_number }}">Next</a>
   {% endif %}
   
</nav>
{% endblock  %}

Best practices and common mistakes when using Django templates

Coherent block names

Avoid mixing names like content, main, body. Always use the same ones throughout the project.

Organization of templates/ folders

Create a clear structure:

templates/
├── base.html
├── products/
│   ├── list.html
│   └── detail.html

Common mistakes

  • Forgetting {% load static %} when using CSS or JS files.
  • Incorrect paths when extending ({% extends "base.html" %}).
  • Unclosed blocks ({% endblock %}).

Conclusions: why a master template improves your development in Django

Since I started using a base template, my Django projects are much easier to maintain.
I no longer repeat code or waste time making changes in multiple views.
Reuse becomes a natural part of the workflow and visual consistency is immediate.

If your app has more than two pages, you need a master template. It's one of the foundations of clean development with Django.

❓ Frequently asked questions about master templates in Django

What is a master template in Django?
It is a base template that defines the main structure of the site and allows inheriting common blocks.

How is a base template created?
Create base.html with {% block %} blocks and then extend it with {% extends "base.html" %} in the other views.

Can I have more than one base template?
Yes. You can create one for each app or section (example: admin, store, blog).

How do I add CSS or JS to the base template?
Use {% load static %} and link your files inside the head or before the closing body tag.

What are the benefits of using master templates?
Time savings, simple maintenance, and visual consistency throughout the project.

Now, let's see how to use session in Django.

I agree to receive announcements of interest about this Blog.

Learn how to create master views in Django to reuse templates or generic HTML views and to modularize your application so that it grows in an organized way.

| 👤 Andrés Cruz

🇪🇸 En español