Django – Building Pages & Making a Template

In my previous posts I showed you how to create a basic home page with Django. Here we are going to dive a little deeper, creating a template that will be used while rendering other pages on the website, then create a page that will use the template.

A template allows the same content (headers, footers, side bars, menus, etc) to be repeated on other pages so you don’t have to copy/paste the same code over and over. It also makes it much simpler to maintain the site if your base code is only in a single location!

Step 1 – Create a Parent Template File

To achieve this, we create a file called base.html. This file will contain all our basic template code that will be repeated on every page.

<p>
    <a href="{% url 'burgers:index' %}">ThinkTwisted Burgers!</a>
</p>

{% block content %}{% endblock content %}

The above code may look a little familiar if you’re a web developer, but a bit confusing. We’re combining HTML with Django markup to build our site. Anything enclosed between {% %} instructs Django to process the code as python/Django rather than HTML.

The code above creates the words ThinkTwisted Burgers! that is a link to our index page. The block content tags at the bottom tell Django where the content on other pages will go. This is the basis of our template.

Step 2 – Create a Child Page

Now, we modify our index.html file to use the template and build upon it. Update index.html to match the following code.

{% extends "burgers/base.html" %}

{% block content %}
<p>The Home page for our burgers</p>
{% endblock content %}

Comparing this to the original index.html file, you will notice that we’ve removed our title (it will be generated by the base.html template), and added some block content tags. The {% extends “burgers/base.html” %} lets Django know we are using the base.html template file. It should render anything in that file first, then insert the code between the block content tags.

Step 3 – Add Content to the Child Page

Now, let’s add some useful content to our page. You thought we’d never get here, right? Let’s make a page that shows all the burgers we have available at our restaurant. It will query the database and display the names of all our specialty burgers.

First, we modify the app’s url.py file to add a URL that will direct the user to a burger listing page.

'''Defines the URL patterns for burgers'''
from django.urls import path
from . import views

app_name = 'burgers'
urlpatterns = [
    # Home Page
    path('', views.index, name='index'),
    # Page that lists Burgers
    path('burgers/', views.burgers, name='burgers')
]

Now, we have to add the view (i.e. function) we just named in the URL file to the views.py file. Update views.py to the following code.

from django.shortcuts import render
from .models import Burger

# Create your views here.
def index(request):
    '''The homepage of ThinkTwisted Burger Joint'''
    return render(request, 'burgers/index.html')

def burgers(request):
    '''Show all burgers'''
    burgers = Burger.objects.order_by('name')
    context = {'burgers': burgers}
    return render(request, 'burgers/burgers.html', context)

First, we import the Burger model – from .models import Burger.

Second, we define a function to get all the burgers in the database and organize them by name.

Third, we define a context – this is simply a dictionary used by Django to access the data.

Finally, we return the render request with the context.

Step 4 – Create a Burger List Page HTML file

Now that we have defined the URL and the view, we need to make a page that uses them. We create a burgers.html file that will list them.

{% extends 'burgers/base.html' %}

{% block content %}
    <p>Specialty Burgers:</p>
    <ul>
        {% for burger in burgers %}
            <li>{{ burger }}</li>
        {% empty %}
            <li>No special burgers on the menu!</li>
        {% endfor %}
    </ul>
{% endblock content %}

Look confusing? I agree. Here we’ve extended our base template and added some block content. In the block we’re using a for loop, but we have to enclose it in {% %} in order for Django to know that it is python code. So, we’re telling Django to step through each item in the list of burgers and print them as an HTML list. Any item enclosed in <li> as part of <ul> tags will create a bulleted list item.

We use {% empty %} to tell Django what to do if there is nothing in the burgers dictionary. We know there will be, but this is good practice so your site doesn’t error out as it grows more complex.

Last, we close the for loop with {% endfor %} and close the content block.

Step 5 – Update Base Template

Now that we’ve created the page and view, we have to give site users a way to access it. We’ll add a link on the base.html that can be clicked to get a list of specialty burgers. Modify the file to match the code below.

<p>
    <a href="{% url 'burgers:index' %}">ThinkTwisted Burgers!</a> - 
    <a href="{% url 'burgers:burgers' %}">Specialty Burgers Menu</a>
</p>

{% block content %}{% endblock content %}

Here, we’ve just added a link to the burgers menu page. Navigate your browser to the home page and you’ll see the link to Specialty Burgers Menu, click it! You’ll get a list of burgers like below.

Looks pretty good! Now if only we knew what was on each burger on the menu…check out the next article in this series to learn how to add a feature that will display all the toppings for each burger.

John

Leave a Reply

Your email address will not be published. Required fields are marked *