Django 1.0 Template Development

By Scott Newman
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. An Introduction to the Django Template System

About this book

Django is a high-level Python web application framework designed to support the rapid development of dynamic websites, web applications, and web services. Getting the most out of its template system allows programmers and designers to easily and efficiently output their content in a flexible, extendable, and maintainable manner.

This book will help you to master the Django template system. Built-in template tags and filters are explained with examples and usage notes, as well as information on building custom tags and filters to extend the system for your needs. You will learn to use inheritance to create modular templates that are easy to maintain. You will learn how to serve multiple templates from within the same Django project, with an example of how to serve different templates for a mobile version of your site without having to change any code in your views. Pagination, internationalization, caching, and customization of the automatic admin application are also covered.

Publication date:
December 2008
Publisher
Packt
Pages
272
ISBN
9781847195708

 

Chapter 1. An Introduction to the Django Template System

Django simplifies the process of creating data-driven applications and provides a flexible, modular approach to web development. In contrast to many other web application frameworks, Django is full stack, which means it contains all the libraries and packages necessary to create applications. Because the pieces were designed as a whole, you can develop using them with the confidence that they will all work well together. One of these pieces is the Django template system that allows output to be formatted in a flexible, consistent, and maintainable fashion.

In this chapter we will:

  • Learn what templates are and why you should use them

  • Review how Django handles requests

  • Learn the syntax used in the templating system

  • Set up a demo application that we will use throughout this book

 

What are templates?


The term template can have different meanings depending on what programming environment, language, or framework you are working in, so let's clarify what it represents to Django developers. In Django, a template is a string that can be combined with data to produce output. Typically, templates are stored as files on the file system, and contain placeholders that are replaced with information from the database and the results returned as HTML documents.

Understanding the need for templates

In some development platforms, such as PHP and ASP, the programming code and the HTML markup is all contained in a single file that gets processed and returned by the web server. In complex pages, this approach can become difficult to develop and maintain because there isn't a separation between the presentation and the programming logic used to render it.

Having programming logic mixed in with your markup code also limits the ability for designers to work in the files, unless they also understand the bits of programming logic sprinkled within. This makes changing the markup both tedious and time-consuming because the developer usually has to do the updates.

This clearly isn't a productive way to develop applications. We end up with a number of requirements that need to be addressed:

  • We need to separate the output markup from the Python code

  • The system should encourage reusability and maintainability of output files

  • Common page elements should be contained in their own files and easily included into the overall structure of the site

  • Designers and developers need to be able to work without getting in each other's way

  • The system should have a shallow learning curve and only require a basic understanding of programming concepts

  • The system needs to be extensible and flexible enough to fit the specific needs of our projects

 

Overview of the Django template system


The Django template system fits all of these criteria nicely. By separating code and content, allowing only basic programming constructs, and making it possible to write your own extensions to the system, the Django authors have created a solution that works well for both designers and developers.

Separating code from presentation

Instead of mixing programming code and presentation markup (such as HTML) in the same files, we create templates that have placeholders where the data will go. When the template engine renders the templates, these placeholders are replaced with their appropriate values. By the time the output is returned to the web browser, all traces of the template have been removed, leaving only the resulting output.

As we have seen, Django templates, typically, are files loaded by the template engine and rendered into output that will be sent back to the browser. This loading and rendering takes place in the view, the function that Django calls to fulfill requests.

Note

In some web development frameworks, the terms view and template are used differently. In Django, the view is a Python function that is called by the framework to return an HTTP response. The template is a file or string that encapsulates the presentation markup that is used to generate the response.

In order to accomplish basic output logic, such as looping through records and creating table rows, some programming code needs to exist in the template files. The amount of programming you can do in your template depends on your programming language or framework; Django allows basic looping and conditional logic. The process of rendering executes this template logic and replaces placeholders with data.

Helping designers and developers collaborate

By separating templates out of framework code into their own files, developers and designers can work simultaneously on the same project without stepping on each other's work. This approach has the added benefit that there is a clear differentiation between design and development; coders stay out of the design arena and designers stay out of the programming arena—we can live in harmony! (Well, maybe...)

Keeping the template clear of code also makes it easier to work in WYSIWYG (What You See Is What You Get) editors such as Dreamweaver and Homesite. We're not going to cover that in the book, but it's worth mentioning.

Increasing maintainability

The template files are usually located in their own folders nested somewhere in the Django project. The templates can include other templates in them, and so common page elements such as menus, headers, and footers can be kept in their own files. Including common elements from single files increases the maintainability of our application by reducing the amount of common output markup that is duplicated in different files. Instead of hunting around for all the occurrences of some HTML to replace, we can make the change in one place and all templates that include the content will be updated automatically.

Templates can also have parent templates that simplify the development of sections of a site. For example, if we have a calendar listing in the events section of a website, we might use three templates:

  • A child template that handles the listing of calendar items

  • A parent template that handles the formatting of the events section of the site

  • A grandparent template that handles the formatting of the overall site

This prevents the duplication of site- and section-wide HTML by keeping them in single files. We'll explore the parent-child relationship and inheritance of templates in great detail in a later chapter.

Template syntax

The syntax of the template system is intentionally clean, simple, and elegant. With a minimal understanding of programming concepts, you can make powerful and flexible templates to output your data.

We'll cover these concepts and the syntax of the template language later in this chapter.

Modularity and reusability

Django ships with many built-in template elements that we can use to control and format the output of our templates. You can also write your own template elements, if you have a need that isn't met by the default libraries, or use ones that other developers have written. Sites such as DjangoSnippets.org contain many template libraries that developers have shared and can be easily incorporated into your own site.

In a later chapter, we'll cover writing your own template element libraries and how to install and use libraries that others have written.

Flexibility

The template system is flexible enough so that we can output any kind of data that we want. It doesn't assume (or require) that you are going to produce HTML. We can dynamically generate PDF documents, CSV files, HTML files, microformats, and text documents. It also doesn't require you to write your templates in any specific format (such as XML) the way some other Python templating languages do.

Even though you can extend the template system with custom elements to fit your needs, the Django creators gave us the ultimate back door—You don't have to use their template system! You are free to implement any Python template system and libraries of your choice, and you can do it on an as-needed basis in only the places you desire. For example, if you want to use the Django template system for half of your views and the open-source Genshi templating system for the other half, there's no penalty.

Limitations

The elegance and simplicity of the Django template system comes at a price; there are a few limitations to be aware of. In a nutshell, only the processing of simple presentation logic is supported in templates. You can loop over sets of data and check the value of objects and variables to perform conditional logic, but you cannot perform complex logic and execute raw Python code.

Here are a few things you cannot do using the Django template system syntax:

  • You cannot execute arbitrary Python code inside a template.

  • You cannot set or modify the value of variables inside a template.

  • You cannot pass arguments to the methods of objects inside a template.

If you need to perform these kinds of actions, you can often write your own extensions to the template system. We will fully cover these limitations and their implications later in the book.

Critics of the system

Some critics argue that the Django template system is too simple and isn't robust enough to perform complex formatting or outputting. This may be true, but remember that these limitations are intentional to achieve the design goals we discussed earlier. You're also free not to use Django's template system and use a more liberal template library if you choose.

Note

Personally, after using Django's template system on a team of designers and developers for almost two years, I find that the simplicity and elegance of the system results in disciplined application design. This simplicity enforces consistency in the templates, and makes developers consider the output and prepare their data properly before sending it off to the templates to be rendered. This prevents logic from creeping into the templates as deadlines start to loom and developers cut corners to meet them! (Not that any of us would do that, of course!)

 

Exploring how Django handles requests


In order to understand how the template system works in conjunction with the rest of the Django framework, we should briefly explore how a request is handled. Understanding this process isn't critical to working with templates, but it will help you make sense of what is happening. This isn't an exhaustive explanation, but it should get us through a basic understanding of what is happening beneath the covers.

Here's how a typical request is handled:

  1. A URL is requested.

  2. The middleware is called.

  3. The URL is evaluated.

  4. The middleware is called (again).

  5. The view is called.

  6. The template object and template file are loaded.

  7. The template is rendered.

  8. The middleware is called (yet again).

  9. The output is sent to the browser.

Step 1: A URL is requested

The user requests a web page via URL in his/her browser. The web server receives this request and passes it to Python and Django.

Note

Note: We are skipping over the gritty details of DNS, routing, web server interface to Python, and so on. Those are way out of the scope of the book, so just take for granted that Django has received the request properly.

Step 2: The middleware is called

Django has a special mechanism called the middleware that allows you to call functions at a number of places in this request-response cycle. You can invoke a middleware function in four places: before the URL resolution, before the view is called, after the view is called, and if the view raises an exception (if there's a problem).

Note

The middleware at this step is called the Request Preprocessor, but that's extra-credit information.

Step 3: The URL is evaluated

Django's URL dispatcher compares the requested URL with a list of patterns (regular expressions, to be exact). If a match is found, Django imports and calls the view that is associated with the pattern. This process is known as URL resolution.

The view is a Python function that handles the creation of the response. If additional pieces of data have been sent in the URL (such as product IDs, story names, and so on), they are passed as arguments to the function.

Note

Django also has a concept called Generic Views that can automatically load and render a template at this step without having to go any further. We'll look at generic views in a later chapter.

Step 4: The middleware is called (again)

If you have middleware functions to be run after URL resolution but before the view is executed, it will be called here.

Note

The middleware at this step is called the View Preprocessor.

Step 5: The view is called

The view is where the rubber meets the road, so to speak.

The majority of views will use the database API to perform some kind of CRUD (create, retrieve, update, and delete) operation, load a template, render the output, and send it back to the user.

The Python code in the view function is executed at this point. Usually this entails retrieving some kind of data, most often by using the Django database API to retrieve model objects.

Once the data is retrieved, it is passed to a special object called the Context. This is the object that holds the retrieved data and makes it available to the templates. For now, think of it as a dictionary of variable names and values that the template will get. If you are not familiar with Python dictionaries, see the code notes later in this chapter or look in the Python standard documentation.

Note

Models are not required in views, nor is even having a database! Of course, that would be kind of silly, since we're trying to create a data-driven site. It should just be stated that you don't HAVE to have a model to have a valid view.

Step 6: The template object and template file are loaded

The template object is called and gets the appropriate template file from the file system at the location specified in the view. This relative path is combined with the templates directory specified in our project's settings.py file.

As we discussed earlier in the chapter, templates are not technically required to send back responses, but they make your life much easier. We'll see this in the upcoming examples in this chapter.

Step 7: The template is rendered

The text inside the template is rendered. The placeholders are replaced with their associated data and statements of template logic (such as looping) are performed. At this point, the rendered template is just a large Python string of characters.

Step 8: The middleware is called (again)

If you have middleware functions to be run after the response is generated but before it's sent back to the user, they are called at this step.

Note

The middleware at this step is called the Response Postprocessor.

Step 9: The output is sent to the browser

The rendered template is packaged up with formatting that is needed by the browser to understand how to accept and display the page. By adding this formatting, the string has been turned into an HTTP response that is sent back to the browser.

In this example, the response is HTML, but it doesn't have to be. It could also be plain text, XML, JavaScript, CSV, PDF, and so on. Part of the formatting of the HTTP response tells the browser what the MIME type of the response is, and it tells the browser what kind of data to expect.

 

Understanding the template system syntax


Now that we have a basic understanding of how the template system fits into the big picture, we can finally explore some basics of how it works.

As we discussed earlier, Django templates are basically just text files that have placeholders and simple logic in them. These placeholders are evaluated when the template is rendered, and Django replaces them with the values that go in their place.

Let's illustrate with a quick example of a template file:

<html>
<head>
<title>{{ page_title }}</title>
</head>
<body>
<h1>{{ header }}</h1>
{% for name in names_list %}
{{ name.last|upper }}, {{ name.first|upper }}<br/>
{% endfor %}
</body>
</html>

Don't worry if you don't immediately grasp these concepts. We'll be running through a practical example of the syntax at the end of the chapter.

Context variable

If you recall the request-handling overview, we said the context was a special object that contained the values available to the template when it is rendered. We'll work through a practical example later in the chapter. For now, just think of it as a dictionary of variables that the template will be able to see (see the upcoming code note if you don't know what a Python dictionary is).

Variables

Variables are the basic placeholders in a Django template. They are identified by two curly brackets on each side:

My favorite color is {{ color }}.

When the Django template engine renders this page, it will see {{ color }} as a placeholder for the real value it is supposed to put in its place. It looks in the context for a key named color and finds the value associated. If our context has a key named color and an associated value of blue, the output would look like this:

My favorite color is blue.

Filters

Filters can format the output of variables in Django templates. They are identified by the use of a pipe symbol immediately following a template variable:

My favorite color is {{ color|upper }}.

In this example, upper is the filter we are using to modify the variable color. (Notice there is no space between the variable, the pipe, and the filter.) The upper filter will take the value of the variable and convert all the letters to upper case. (Specifically, it applies the Python string function upper() to the value.) Here is the resulting output:

My favorite color is BLUE.

Note

The filters don't change the value of the variables they modify, but just modify the way they are outputted. In our example, if you use {{ color }} somewhere else in your template without the template filter, it won't appear in upper case.

Django ships with a number of default filters that cover many common presentation-formatting needs. You can find them listed in the Django documentation at DjangoProject.com.

Tags

Template tags instruct the template rendering engine to perform some kind of action. They are identified by a curly bracket and percentage symbol, and often have an accompanying closing tag:

{% ifequal color 'blue' %}
  Wow, you like blue!
{% else %}
  Why don't you like blue?
{% endifequal %}

In this example, we are using the template tag ifequal. It takes two arguments, which means the values to be compared. Unlike Python code, we don't use parentheses or commas around the arguments. We just use a space between the template tag and each of the arguments. The tag also has a corresponding closing tag endifequal that tells the template engine we are done.

In this example, since the value of the variable is blue, we get this output:

Wow, you like blue!

Like filters, Django ships with a number of default tags that perform common logic in templates such as looping through sets of data. We'll be covering tags and filters in more depth in later chapters as well as writing our own custom tags.

When the templates are rendered, the tags are removed by the template engine. If you view the source of your output, you will not see your tags, though you will probably see a blank space where the tag was.

Comments

There are two kinds of comments we can use in Django templates: single-line and multi-line. Like comments in Python, you can leave yourself notes in a template or use comments to prevent a chunk of template code from being rendered by the template engine. Single-line comments are identified by a curly bracket and a hash mark (also known as the number sign or pound symbol):

{# Remember to move this down the page later #}
My favorite color is {{ color }}.

Multi-line comments are implemented as tags, and they have a corresponding endcomment tag:

{% comment %}
{% ifequal color 'blue' %}
  Wow, you like blue!
{% else %}
  Why don't you like blue?
{% endifequal %}
{% endcomment %}

In this example, the template engine ignores everything between the comment and endcomment tags. This is often used to troubleshoot and debug a section of template that isn't behaving properly.

Like template tags, single- and multi-line comments are removed from the resulting output by the template engine. They are not the same as HTML comments; you won't see them if you view the source of your output.

Code note: Python dictionaries

In case you are not familiar with Python dictionaries, here is a basic explanation.

A dictionary is one of Python's built-in data types, similar to hashes in other programming languages. It consists of keys and values. The key is the label used to identify the item, and the value is what it is equal to.

Here's an example:

>> mydictionary = {}
>> mydictionary['mykey'] = 'myvalue'
>> mydictionary['myotherkey'] = 10
>> print mydictionary
{'mykey': 'myvalue', 'myotherkey': 10}

The first line tells Python that we are creating a new dictionary called mydictionary. The empty curly brackets tell Python that we are creating a variable that is of type dictionary and not a string or integer. The next two lines add keys and values to the dictionary. The first adds a new key called mykey that has a value of myvalue. The second has a key of myotherkey and has a value of 10.

Note

We can mix numbers and strings as values of the keys. They don't all have to be the same type.

You can also create a dictionary in one step:

>> mydictionary = {'mykey': 'myvalue', 'myotherkey': 10}

This may look a little more complex, but it does the same thing the first three lines of our example above did.

Why is all of this important? It lets us keep all of our values grouped under a single variable. In the Django template language, the Context holds a dictionary of all the values we are going to make available to our template. When Django passes the dictionary to the template, the keys are what the placeholders are going to work with to be replaced with their values.

How invalid variables are handled

If you try to use a variable in your template that has not been made available to the context object, you will not get an error. The template system simply ignores it and keeps on going. This was a design decision by the Django developers to prevent a missing data item from "breaking" an application.

If you have an error with a template tag, however, you will get an error.

 

Creating our demo application


Throughout the book, we're going to work with the same example site so that we don't have to set up a new project for every chapter. This project will explore all the concepts throughout the book.

Rather than work with the clichéd example of a blog, we'll work with example applications that you'd find in a typical corporate website, such as news and press releases. If you've ever worked a corporate job, you've probably done something like this (and if you haven't, stick it on your resume when you're done!).

The specific configuration directives (project file system locations, database names/passwords, and so on) are given to maintain consistency throughout the book. Feel free to change them to suit your specific needs, but be sure your settings.py file matches your setup. If you decide to put the project in a different directory on the file system than what is used here, make sure to change your code appropriately when doing the examples in this book. (Hint: It's probably easier to follow along with these values if at all possible!)

Prerequisite #1: Install and test the Django framework

Installing the Django framework is thoroughly covered in the documentation on the DjangoProject.com site. If you have trouble, you can try posting a message to the Django-Users|Google Group (http://groups-beta.google.com/group/django-users).

If you can start a Python shell and successfully run the command import django, you should be good to continue.

Note

At the time of this writing, the latest release of Django is 1.0, so that's what we will be using here.

Prerequisite #2: Create a new database

For purposes of this book, it doesn't matter what database engine you use as long as Django supports it (for example, MySQL, PostgreSQL, SQLite, and so on). If you don't have MySQL or PostgreSQL installed, SQLite is probably the easiest choice to work with as it requires zero administration to set up and use.

If you are using MySQL or PostgreSQL, following the instructions of your specific database engine, perform the following tasks. (If you are using SQLite, you don't have to do this.)

  1. Create a database called mycompany.

  2. Create a user called mycompany with a password of mycompany.

Step 1: Create the Project Directory

Create a file system location for our Django project files. This is one of the couple of places where your settings might vary depending on the operating system you are using:

For Unix/Mac: Create a /projects/ directory.

For Windows: Create a c:\projects\ directory.

Step 2: Start your project

From the projects directory, run this command:

$ django-admin.py startproject mycompany

This will create a mycompany directory under projects.

Note

Note: Rather than writing out both Windows and Mac/Linux versions of the full filesystem path each time we refer to it, the directory will be referred to as mycompany/ instead of /projects/mycompany or c:\projects\mycompany. If you see mycompany/, you can safely assume that we are talking about those directories.

Step 3: Test your installation

In the mycompany directory, run this command:

$ python manage.py runserver

Browse to http://localhost:8000 and make sure you see the blue It Worked! screen.

During development and testing, you will have to keep starting and stopping the development web server. Anytime you need to browse a URL to test your application, you need to have the server running. Some people like to keep it running in a separate terminal window during development. Just be aware that the web server will restart each time you change a file. If you have a typo in your saved file, the web server may stop and display an error message and you'll need to manually stop and start the web server again when this happens.

Step 4: Configure the project's settings

For the upcoming chapters, we need to make sure Django is configured to use our database. In the mycompany/settings.py file, edit the database settings to match what you are using:

DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = '/projects/mycompany/mycompany.db'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''

The settings above are valid if you are using SQLite, which is preferable because it requires no configuration. If you are using a different database engine, such PostgreSQL or MySQL, make sure you configure the settings accordingly. Consult the online documentation if you are having trouble.

Starting our application

We now have an empty skeleton of a project upon which we can start building applications. The first application we are going to work with will just be a demonstration to get us warmed up.

Step 1: Create the demo project

In the mycompany directory, run this command:

$ python manage.py startapp demo

This will create a demo directory under the mycompany directory.

Step 2: Add a detail function to the demo view

In the file mycompany/demo/views.py, add these lines:

from django.http import HttpResponse

def detail(request):
    return HttpResponse('got here!')

Step 3: Add a URL pattern for our demo project

In the file mycompany/urls.py, edit the file to look like this:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^demo/$', 'mycompany.demo.views.detail'),
)

This tells the URL dispatcher that if it matches a URL of http://localhost:8000/demo/, call the detail function inside the file mycompany/demo/views.py.

Note

The URL dispatcher automatically strips the http://localhost:8000/ portion when matching, so we don't need to include it as part of our pattern.

Step 4: Make sure it worked

In the mycompany directory, run this command:

$ python manage.py runserver

This will start the Django development server. You should see something very similar to the following:

Validating models...
0 errors found
Django version 1.0-final-SVN-unknown, using settings 'mycompany.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Browse to http://localhost:8000/demo/. You should see the got here! line we wrote in our view.

Congratulations! We've created our first Django view. We've built a solid base to start from and we're ready to start playing with views, contexts, and (of course!) templates.

Adding templates to our application

The app we built in the last section serves a page, but it's only a starting point for the application we are going to build. Let's use it to explore some concepts of how Django templates work.

Adding variables to the view

Before we start loading templates, we need to explore the Context and Template objects.  As we discussed, the context makes variables and objects available to the templates during rendering. We pass it a dictionary of variables and objects and their associated values. When the template is rendered, the placeholders will be replaced with their corresponding values.

Edit your mycompany/demo/views.py file, adding the highlighted line and replacing your detail function with this one:

from django.http import HttpResponse
from django.template import Context, Template, loader

def detail(request):
    dict_values = {'fav_color': 'blue'}
    template_string = "My favorite color is {{ fav_color }}."
    c = Context(dict_values)
    t = Template(template_string)
    rendered_template = t.render(c)
    return HttpResponse(rendered_template)

Browse to http://localhost:8000/demo/ and you should see the simple one-liner response:

My favorite color is blue.

So what happened here? Let's break it down.

We created a simple dictionary called dict_values and populated a key called fav_color with a value of blue. If you're not familiar with Python dictionary syntax, check out the code note earlier in this chapter or the Python standard documentation under 'Data Structures'. You'll want to be familiar with this syntax; it's used quite a bit with Django.

We also created a string named template_string that contains our first taste of the Django template syntax. The double brackets in the string are simply the delimiter used to identify template variables. {{ fav_color }} tells the template rendering function that this is a placeholder for the value of the variable fav_color.

Next, we created a context object named c and passed it our dictionary. We also created a template object called t and passed it our template string.

Note

Templates don't have to be stored as files, they can also be strings. When you load a template, Django opens the file and extracts the text into a variable. We're keeping the example simple to start with here and just using a string to represent our template.

When we call the render method of the Template object, it parses the template string and replaces any template variables and logic with the appropriate values. In this case, {{ fav_color }} was replaced with the value blue. The rendered template is returned as a string to the rendered_template variable.

Finally, we send the value of the variable rendered_template to the browser as an HTTP response. Django nicely handles all the necessary steps of properly formatting the output for the browser to do its work and displaying the HTML.

Keep in mind that the verbosity of this example is intentional to keep the example clear. If you are familiar with Python, you'll know it could be written more concisely like this:

def detail(request):
    c = Context({'fav_color': 'blue'})
    t = Template("My favorite color is {{ fav_color }}.")
    return HttpResponse(t.render(c))

Moving the logic into a separate template file

Templates are usually longer than five words, so let's put the template string into a separate file.

We need to create a templates directory in our project. Technically, the templates could go anywhere on the file system, but it is common to put them under a templates directory at the root of your project. Create a directory called templates under the mycompany directory.

In your mycompany/settings.py file, find the TEMPLATE_DIRS variable (it's actually a Python tuple) and add a reference to our new templates directory:

TEMPLATE_DIRS = (
    '/projects/mycompany/templates/',
)

Note

In Windows, use the value c:/projects/mycompany/templates/. The slashes don't follow the normal Windows syntax, but it's what Django requires.

Even though we are only specifying a single directory of templates, make sure you have the trailing comma after the file path in TEMPLATE_DIRS. If you omit it, Python will treat your TEMPLATE_DIRS variable as a string, not a tuple, and you'll get an error when you try to run it.

Note

Adding a trailing comma in a list or tuple is also good practice since Python allows trailing commas. If you always leave a comma after your last item, you won't forget to add it the next time you add another item to the end of the sequence.

While we are in the settings.py file, let's enable debugging for our project by setting the DEBUG and TEMPLATE_DEBUG variables at the top of the file to True:

DEBUG = True
TEMPLATE_DEBUG = True

This will ensure that Django shows us error pages with debugging information instead of a blank page.

Now that we've told Django where to find the templates, let's create a file called example.html in the mycompany/templates directory. In the file, add the line that was in our detail view:

My favorite color is {{ fav_color }}.

We need to change our view to load this new template file. Edit your mycompany/demo/views.py file and change the detail view to look like this:

def detail(request):
    c = Context({ 'fav_color': 'blue' })
    t = loader.get_template('example.html')
    rendered_template = t.render(c)
    return HttpResponse(rendered_template)

Browse to http://localhost:8000/demo/ and you should see the same response that we got before we created the template file:

My favorite color is blue

Using template filters

If we want to modify the output of a variable, we can use a template filter. Filters modify the way a context variable is displayed in the output. As we saw earlier, they are applied using a pipe symbol directly after the variable. Do not put a space between the variable and the pipe.

To make the value of our fav_color variable be displayed entirely in capital letters, we can use the upper filter. In your mycompany/templates/example.html file, add the upper filter to the template fav_color template variable:

My favorite color is {{ fav_color|upper }}.

Browse to http://localhost:8000/demo/ and you should see this output:

My favorite color is BLUE

Using template tags to perform logical tests

We've already seen how variable substitution takes place. So let's use a template tag to perform some simple logic to compare values.

We're going to use the ifequal tag to test if the fav_color context variable has the value blue. The tag uses this syntax: {% fequal <argument1> <argument2> %}

Change your mycompany/templates/example.html template file to look like this:

{% ifequal fav_color 'blue' %}
  My favorite color is {{ fav_color }}.
{% else %}
  My favorite color is not blue.
{% endifequal %}

Browse to http://localhost:8000/demo/ and you should see this output:

My favorite color is blue.

We can also use template tags to perform looping logic. It is very common in a template to loop over a set of values and perform an action on each value. Let's add a second color to our context variable and use a for loop in our template to write them out.

First, in your detail view, change your fav_color variable to a list of colors by using Python list syntax:

def detail(request):
    c = Context({ 'fav_color': ['blue','green'] })
    t = loader.get_template('example.html')
    rendered_template = t.render(c)
    return HttpResponse(rendered_template)

We'll use the for and endfor tags to loop through the list of favorite colors. Notice that we are using a variable called color to hold the value for each iteration of the loop. In this example, fav_color is our list of colors from the Context, and color is the current value in the loop. Make sure you change the variable in the curly brackets to use color.

Replace the contents of your mycompany/templates/example.html file with these lines:

{% for color in fav_color %}
  My favorite color is {{ color }}.<br/>
{% endfor %}

The resulting output will look like this:

My favorite color is blue.

My favorite color is green.

Adding comments

If you want to add comments to your templates, you have two options: single-line and multi-line comments. If you want to make a comment that only spans a single line, you can wrap your comment with a curly bracket and hash (pound sign) syntax:

{% for color in fav_color %}
  {# We are writing out a comment here #}
  My favorite color is {{ color }}.<br/>
{% endfor %}

If you want to make comments that span multiple lines, you can wrap your comments in a comment tag. Note that the comment tag requires an ending endcomment tag:

{% comment %}
My comment
is more than 
one line long
{% endcomment %}
 

Summary


That's it for our Django introduction and templating overview. Hopefully, you were able to follow along and got a taste for what we'll be covering in this book.

In this chapter, we:

  • Discussed why templates are critical to development

  • Explored how Django processes requests

  • Covered the syntax of Django templates including filters, tags, and comments

We also set up a new Django project and configured it to run a test application. This project will be used throughout the book, so make sure you were able to get it working before continuing.

In the next chapter, we'll look at views and generic views to understand where templates get loaded and rendered.

About the Author

  • Scott Newman

    Scott Newman has been developing commercial websites since 1997. Since then, he has professionally developed web applications in C, PERL, ColdFusion, ASP, PHP, and Python. He has also been a Windows network administrator and desktop application developer, but always gravitates back to web development. Scott holds a Network+ certification and is a dotMobi Certified Mobile Web Developer.

    In recent years, Scott worked as the system development manager for a major media company developing CMS and mobile applications in Django. He is currently the consulting director for the Big Nerd Ranch in Atlanta, GA.

    Browse publications by this author
Book Title
Access this book, plus 7,500 other titles for FREE
Access now