Beginner Lesson 6: Create Site Templates


Transcript References
The video mentions copying code from the screen or transcript. This is a reference to the old, paid version of the course. I have now collated all the code together in one place in the source, which you can download here.

In Module 4, we created a very simple view to display a message in the browser. This is obviously a long way from a fully functioning, modern website. For one we’re missing a site template.

Site templates, at their most basic, are HTML files that are displayed by your browser. All websites—from simple, static pages to interactive web applications that work on multiple devices—are built on HTML.

Modern interactive websites are more complex. For example, a modern website will add Cascading Style Sheets (CSS), semantic markup and JavaScript in the front end to create the user experience with a back end like Django supplying the data to show in the template. However, the fundamentals stay the same.

Django’s approach to web design is simple—keep Django logic and code separate from design. This means that it’s possible for a designer to create a complete front end that includes HTML, CSS, imagery and user interaction without ever having to write a single line of Python or Django code.

In this module you’ll learn how to build a simple HTML site template and then add Django template tags to the HTML files to create a template capable of displaying data from the database.

Before we do this, we need to dive back into your project settings and structure so you can understand where Django looks for templates and how it decides which template to display.

Template Settings

For Django to show your site template, it first must know where to look for the template file(s). This is achieved by the TEMPLATES list in By default the TEMPLATES list contains a dictionary of settings for your templates.

Let’s have a closer look at this file:

On line 58 the DIRS key contains a list of paths to folders containing templates. Paths can be absolute or relative. The default is an empty list.

And in line 59, APP_DIRS is set to True by default. When APP_DIRS is set to True Django will look for a folder named templates in each of your apps.

Not all template files will be tied to a particular app. The DIRS setting is useful for linking to templates that exist elsewhere in your project structure. In our project, we’ll have a site template that is not a part of the pages app, so we need to add a path to DIRS. Pause the video and enter this text into your editor or copy it from your transcript.

This looks complicated, but is easy to understand—we’re using Python to create a file path by joining strings together (concatenating). In this example, we’re appending mfdw_site/templates to our project path to create the full path to our templates.

Before we move on, we need to create a templates folder in our site folder. Once you have created the new folder, your project structure should look like this:

        # more files ...

Static Files

Django treats static files—images, CSS and JavaScript—differently to templates. Django’s creators wanted it to be fast and scalable, so right from the beginning Django was designed to make it easy to serve static media from a different server to the one the main Django application was running on.

Django achieves speed and scalability by keeping static media in a different directory to the rest of the application. This directory is defined in the file and is called static by default.

We need to add another setting so that Django can find the static files for our site. Add the following below the STATIC_URL setting. Pause the video and enter the code into your editor or copy it from your transcript:

STATICFILES_DIRS = [BASE_DIR / 'mfdw_site/static']

The STATICFILES_DIRS list serves the same function for static files as the DIRS list does for templates. In this case we’re telling Django to look for static files in the static folder in our site folder. Now we need to create a static folder in our site folder.

Once you have created the new folder, your project directory will look like this:

# more files ...

Site Template and Static Files

Now we’ve configured Django to be able to serve our templates, it’s time to create our site template and static files. We’ll be creating four files:

  1. base.html. The base HTML template for our site
  2. main.css. CSS styles for our template
  3. logo.jpg. 30×30 pixels image for the logo
  4. top_banner.png. 800×200 pixels banner for the site

As the base.html and CSS files are quite large, I don’t expect you to enter them manually, however if you do want to type them out, they’re listed in the transcript. The comment at the top of each listing shows you where to create the file.

I also don’t expect you to create the two small media files that we’re using in the template, so I have included them as well as the CSS and base.html files in the file.


The base.html file needs to be put in the \mfdw_site\templates\ folder. Let’s have a closer look at this file:

This file is mostly plain HTML5 markup. Note the semantic elements—<aside>, <section> and <footer>. Semantic elements provide additional meaning to the browser on how a piece of content should be treated. If you are not familiar with HTML and want to learn more, you can check out W3schools.

The base.html template also includes your first Django template tag—{% static %}. The static tag is used to link media in your templates to the STATIC_ROOT of your project. As we are in development and haven’t configured Django for production, STATIC_ROOT is the same as your STATIC_URL setting (/static/). This is how we put the static tag to use in the template:

First in Line 1, we load the static tag into the template; Then, wherever we need to load static media, we pass the media filename (e.g., logo.jpg) to the static tag, which will automatically prepend the static media directory (e.g., /static/ logo.jpg). You can see this in action in lines 7, 12 and 13.


Main.css needs to be put into the \mfdw_site\static\ folder.

This file is standard CSS. If you are not familiar with CSS, you can either learn more about style sheets as you go, or if you want to learn more now, you can check out W3schools.

The logo.jpg and top_banner.png files can either be extracted from the Module 6 zip file, or you can create your own. Either way, they both need to be put into the \mfdw_site\static\ folder.

Like the Content? Grab the Book for as Little as $5!

Other than providing you with a convenient resource you can print out, or load up on your device, buying the book also helps support this site.

eBook bundle includes PDF, ePub and source and you only pay what you can afford.

Get the eBook bundle here.

You can get the paperback from Amazon.

Updating Your View

Now we have the template and static files in place, we need to update our file. Pause the video and enter the code into your editor or copy it from your transcript.

For our new view, we have replaced the call to HttpResponse() with a call to render(). I have commented out the original lines so that you can more easily see the changes. You don’t have to remove the import from django.http, but it’s good practice not to import modules that you are no longer using.

render() is a special Django helper function that creates a shortcut for communicating with a web browser. If you remember from Module 4, when Django receives a request from a browser, it finds the right view and the view returns a response to the browser.

In the example from Module 4, we simply returned some HTML text. However, when we wish to use a template, Django first must load the template, create a context—which is basically a dictionary of variables and associated data that is passed back to the browser—and then return a response.

You can code each of these steps separately in Django, but in the vast majority of cases it’s more common (and easier) to use Django’s render() function which provides a shortcut that provides all three steps in a single function.

When you supply the original request, the template and the context directly to render(), it returns the appropriately formatted response without you having to code the intermediate steps.

In our modified, we are simply returning the original request object from the browser and the name of our site template.

Once you have modified your file, save it and fire up the development server. If you navigate to the site root, you should see your shiny new site template.

The Pages Template

Now we’ve got the site template up and running, we need to create a template for our pages app. If you remember the DRY principle from Module 1, we don’t want to repeat the same information in all our templates, so we want our pages template to inherit from the site template.

Implementing inheritance is easy in Django—you define replaceable blocks in each template so that child templates can replace sections of the parent template with content unique to the child. This is easier to understand with an example, so let’s modify our base.html file. Pause the video and enter the code into your editor or copy it from your transcript.

The two lines of code we have added are a set of Django block tags. Block tags have the following form:

{% block <name> %}{% endblock <name> %}

The second <name> declaration isn’t required although it’s highly recommended, especially if you are using multiple block tags. You can name your block tags anything you like—in our example, we’re naming the block tag “content”.

A block tag defines a block of template code that can be replaced by any child templates that inherits from the template.

Next, we need to create a template for our pages app that inherits from the site template. If you remember from earlier in the module, the APP_DIRS setting defaults to True. This means that Django will search all your apps for a folder named “templates”.

Go ahead and create a templates folder inside your pages app now. We then need to create another folder inside that. This second folder is named pages after the app. Your pages app folder structure should look like this when you are done:


So, why a second pages folder?

What if you have two apps in your project that each have a template named index.html? Django uses short circuit logic when searching for templates, so when it goes searching for templates/index.html, it will use the first instance it finds and that may not be in the app you wanted!

Adding the inner pages folder is an example of namespacing your templates. By adding this folder you can make sure Django retrieves the right template.

Let’s go ahead and create our page template—page.html. Pause the video and enter this code into your editor or copy it from your transcript.

Let’s have a closer look at this:

Line 1 is where the magic of inheritance comes in. We’re telling Django that the page template extends, or adds to, the base (site) template.

And in lines 3 to 6, we’re declaring a set of block tags named “content”. This block will replace the block of the same name in the parent template.

Notice that we have not repeated a single line of code from base.html— we’re loading the file with the extends tag and replacing the content block with a new content block.

Now that we’ve created the page template, we need to modify to show the template. Pause the video and enter the code into your editor or copy it from your transcript.

Only a small change this time—instead of using the site template, we’re now using the page template. If you run the development server, your home page should look like this.

Notice that it’s saying “This is the page template”, not “This is the site template”. This demonstrates that, with only a few lines of code, Django’s templates allow you focus on the things that are different on the page and ignore the parts that are the same.

Which I’m sure you’ll agree is really cool.

Up Next…

Scroll to Top