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
Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter