Book Image

Django 1.0 Template Development

Book Image

Django 1.0 Template Development

Overview of this book

Table of Contents (17 chapters)
Django 1.0 Template Development
Credits
About the Author
About the Reviewers
Preface
Index

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 %}