
Did you notice at the end of the last chapter that we now have repeated code in our template files? This will become unmanageable as we add more templates to our site: if we want to change the head tag, weāll need to change it in every template.
Letās see howĀ to apply theĀ DRY principle Ā - Donāt Repeat Yourself - and avoid repeated code in our templates by using a base template.Ā
To begin, we need to look at our existing templates and ask two questions:
What is different between these templates?
What stays the same?
The common elements betweenĀ the three templates are:
<html> tag
<head> tag
<title> tag
<body> tagĀ
As these tags are common to every page, weāre going to define them in one place - our base template.
Letās put this site-wide HTML into a new template file at ālistings/templates/listings/base.html.ā Note the code we add at line X:
# listings/templates/listings/base.html
<html>
<head><title>Merchex</title></head>
<body>
{% block content %}{% endblock %}
</body>
</html>Within our HTML, we added a Django template tag - theĀ Ā blockĀ tag. And weāve closed that tag with anĀ Ā endblockĀ tag.
Weāve given this block a name too:Ā Ā contentĀ .
We can look at theĀ Ā blockĀ tag as a placeholder, into which we can inject content - in that sense, they are similar to template variables.
So what we want to do next is to inject our page-specific HTML into this block. Letās return to our page templates to see how.
Open upĀ the āhello.htmlā template. First, remove all HTML that weāre now defining in our base template. (Iām also removing some of the example code I added in the last chapter.)Ā You should end up with something like this:
# listings/templates/listings/hello.html
<h1>Hello Django!</h1>
<p>My favourite bands are:</p>
<ul>
{% for band in bands %}
<li>
{{ band.name }}
</li>
{% endfor %}
</ul>Great, now our page template contains only content that is specific to this page.
Next, add these additional template tags at the top and bottom of the template:
{% extends 'listings/base.html' %}
{% block content %}
<h1>Hello Django!</h1>
...
</ul>
{% endblock %}TheĀ Ā extendsĀ template tag at the top tells Django that we want this template to inherit from our base template.Ā
Surrounding our content, we have an opening and closingĀ Ā blockĀ tag - and weāve given the opening tag the same name as our base template:Ā Ā contentĀ .Ā
As you may have guessed, DjangoĀ will take everything inside the content block in our page template and inject it into the block of the same name in our base template. Letās look at this in action:

Your page should appear exactly as it did before. We havenāt changed how it looks - but we have changed how things are working in the background. This will makeĀ the app easier to manage as it grows.
Of course, now that we have our base template defined, we can use it for all the existing (and future) pages on our site. At the end of the chapter, you'll apply your base template to all of your pages.
Letās visualize what we just did with base templates:
If you need to check any of these steps further, watch the screencast for a recap.
With our siteāsĀ Ā <head>Ā tag defined in our base template, nowās a good time to add a stylesheet.
Files like CSS stylesheets are known as static files in Django because they don't change once the application is running.Ā
YouĀ put static files in a specific place in an app. Create a folder at listings/static/listings/ - and inside it, create a new file called āstyles.css.ā
* { background: red }This is not the final stylesheet weāll use for real in our app - itās more like the āHello World!ā of stylesheets. Itās going to give every element on our page a red background. This is just to test that our stylesheet is loading correctly!
Open up bands/templates/bands/base.html, and letās add aĀ Ā <link>Ā tag below the title to load our stylesheet:Ā
<html>
<head>
<title>Merchex</title>
<link rel="stylesheet" href="{% static 'listings/styles.css' %}" />What do you notice about theĀ Ā hrefĀ attribute of ourĀ Ā <link>Ā tag?Ā
It is another template tag! ThisĀ Ā staticĀ tag tells Django that it should look inside the special static directory we created earlier and find the file we created: ābands/styles.cssā.Ā
For theĀ Ā staticĀ tag to work, we first need to āloadā it into this template. We do that by adding aĀ Ā loadĀ tag at the very beginning of the file, like this:Ā
{% load static %}
<html>
...Here areĀ the results in the browser:

You should see an unsightly red page. This means everything is working!
Once youāre sure your CSS file is loading correctly, you can then edit the CSS file and begin to style your site how youād like it. This course doesnāt cover CSS, but you can either follow this CSS courseĀ or use your existing skills to style your site.Ā
Alternatively, you donāt have to style the site at all - many of the HTML elements weāll be using in this course will have default styling applied to them by your browser. If youāre happy with that, you can simply use a blank CSS file. This is what Iāll do for the rest of this course.
You can follow along again with the concepts from this section in this screencast:
Of course, this base template weāve created can be used for our other pages too - and thatās what Iād like you to do now.
Update each of your page templates, so they all inherit from your base template.
If you get stuck, remember that each of your page templates should end up having:
AnĀ Ā extendsĀ tag.
AĀ Ā blockĀ tag.
AnĀ Ā endblockĀ tag.
Weāve covered the three main components of MVT architecture - the M, V, and T - and youāve seen how separating our app into these three areas helpsĀ you with āseparation of concernsā - decoupling the different parts and applying the single-responsibility principle.
Everything in MVT has a proper place: models, views, templates, and even URL patterns are all separated into their own files.
One of the benefits of having templates in their own files is that a front-end developer can work on the template files, while a back-end developer can simultaneously work on the model and view files. This reduces (not eliminates) the likelihood that the two developersā changes will conflict with each other.
Is MVT/Django always the right choice though?Ā
When I discovered Django, I thought I would never have to learn another framework again! Itās tempting to see it as a silver bullet that solves all of your problems. But it is not always the best choice.
First, Django is a monolith framework. It provides engines for all parts of the application - the template engine for presentation, the ORM for persistence, etc. What if you wanted to swap out one of these parts? It might be better to custom build your MVC/T architecture from parts you choose - like Flask, SQLAlchemy, and so on.
Second, MVC/T is just one architecture style. Itās very well suited to simple CRUD applications. But for enterprise solutions, you could investigate alternatives like clean architecture.
For now, just understand that MVC has its limitations, and you may one day find that you reach one of these limits!
Server-side rendering is the āold-fashionedā way of rendering the HTML content for a web page, where each page load involves a relatively slow round trip to the server. Today, there are many frameworks for creating rich front-end applications in the browser, where the HTML is generated client-side. Thus, only a minimal amount of data is sent between browser and server, resulting in lightning-fast applications.
But that doesnāt mean that you should ignore server-side rendering! On the contrary, itās a great place to start. And for many applications, server-side rendering is an adequate solution. Itās simple to understand. It reduces the complexity of the app as it doesnāt require you to build a REST API. And your app can fit in one repo because thereās no need for a separate JavaScript front-end app. Thatās why server-side rendering with Django is great for proof-of-concept apps and those with simple interfaces.
If the needs of your application change, you can convert your server-side rendering Django project into a REST API using the Django REST framework.
A base template is a place to define site-wide HTML once, in a single place - keeping your HTML code DRY.
Page templates are then left containing only page-specific HTML code.
DefineĀ Ā blockĀ template tags in your base template - these act as placeholders into whichĀ you āinjectā the content from your page templates.
A base template is an ideal place to load a CSS file using theĀ Ā staticĀ template tag.Ā
And with this chapter, weāve covered all of the fundamental elements of MVT architecture! Now you'll take a quiz to review your understanding. Iāll see you in the next part of the course!