Generate the master or base template in an app in Django

Generating a base view for our app is a FUNDAMENTAL process so that our applications are maintainable and more easily scalable, since in our case it means that we have a couple of views, the index view for the list, and the detail view 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:

<!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 skeleton of the body or HTML is repeated in both and the only thing that changes is the content that we display in the middle.

So what if you want to add a CSS, JS, 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 is simple, since there are only 2 templates of our app in Django, but what happens if your application costs 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>

As you can see, here we have the base body, the HTML tag, body... and the blocks (block) 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 list... and the title; each block has to have a name, which is the ID.

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

Now, what we have to do is tell our templates that we want it 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 from where we inherit said template; how will we do next

Adapt the list 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 list 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  %}

Conclusions

As you can see, this is an excellent scheme with which you can reuse common components, in this case the view, and whose reuse term is one of the main characteristics of this type of framework.

- Andrés Cruz

En español
Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.