Chapter 7. Implementing Django Templates to Create Custom Views

<feature><title>What You’ll Learn in This Hour</title> <objective>

How to configure the template directory for a project

</objective>
<objective>

How to create templates in the Django shell

</objective>
<objective>

How to render views using templates

</objective>
<objective>

How to extend templates

</objective>
<objective>

How to embed templates in other templates

</objective>
</feature>

So far, all the examples of web pages that you have created in your views have been hard-coded by Python code that generates an HTML web page. This has worked well because the web pages that you have created have been basic.

As you create more advanced web pages, you will want to begin using the Django template system. The Django template system allows you to write template files that define the presentation of the web page independent of the data. This means that you can write generic web pages and then use the Python code in the views to generate dynamic content inside them.

Using the template system has several benefits. For example, an HTML developer could be working on the web page views, and a Python developer could be working on processing the data at exactly the same time.

In this hour, you will get a chance to create some HTML templates and use them to render the data in your views.

Configuring the Template Directory

The first step in adding templates to your website is to create and configure a directory to store them in. You will want to create at least one directory to store the templates in and then add that directory to the TEMPLATE_DIRS setting in the project’s settings.py file.

Django’s template engine will read the TEMPLATE_DIRS setting and use the directories that are configured there to process the relative paths you will specify for the template.

Creating a Template

Django templates can combine a Django placeholder and just about any type of raw text code that displays a web page. Django placeholders are designated by encapsulating them in double braces:

{{ person_name }}

The raw text portion of the file can contain various types of information. The best way to explain this is with some examples. The following sections take you through some different methods of creating and using Django templates.

Creating Templates in the Django Shell

The first example we will look at is using Django templates in the Django shell to format text output. You probably won’t use templates in the shell. However, the shell is a great place to learn about them and try them out.

To create a template in the Django shell, first import the Template object class from the django.template project using the following command:

from django.template import Template

By the Way

You can use the following command from the root of your project to start the Django shell:

python manage.py

You create a template by calling the constructor of the Template class and passing in a string containing a placeholder. For example, the following line of code defines a Template object t that contains a variable placeholder emotion:

t = Template("I feel {{emotion}}.")

Next, you create some Context objects by calling the Context() constructor and passing it a dictionary that contains the emotion key:

from django.template import Context
c1 = Context({'emotion': 'happy'})
c2 = Context({'emotion': 'fine'})
c3 = Context({'emotion': 'good'})

By the Way

You can change the contents of Context by treating it as a Python dictionary. For example, to change the emotion of the c1 Context object in the preceding example, you could use the following line of code:

c1['emotion'] = 'cool'

After you have created the Template and Context objects, you can render the template to text by calling the render() function of the Template object and passing the appropriate context, as shown in Figure 7.1.

Creating and rendering a template in the Django shell.

Figure 7.1. Creating and rendering a template in the Django shell.

The render() function reads the dictionary in the context and replaces variable placeholders in the template that match keys in the dictionary with the key’s value.

Did you Know?

If you have a lot of text that needs to be processed as a template, you can store the template text as a text file and then use Python’s file functions to read in the contents of the template as a string. This also works when you use the Django shell to test your HTML templates. For example, to read the contents of a myTemplate.html file into a Template object, you could use the following line of code:

myT = Template(open('myTemplate.html', 'rU').read())

Creating HTML Templates

Most of the templates you will work with in your Django website will be HTML templates. HTML templates are text files that contain mostly HTML code but do contain some variable placeholders. You will be able to render the HTML template, using custom contexts, as a response to an HTTP request. Using this method, you can write your web pages using basic HTML tags but still can programmatically control the variable content.

The best way to create an HTML template is to first create an HTML file with the look and feel that you like and test it in a web browser. Then add the variable placeholders for data that needs to be dynamic. For example, test.html, shown in Listing 7.1, displays the simple web page shown in Figure 7.2.

Example 7.1. Full Contents of the test.html File

<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us" xml:lang="en-us" >
<head>
<title>Title</title>
</head>
<body>
<table width=100%>
<tr bgcolor="aabbcc"><td colspan="2">
<font size="12" color="white">Title</font>
</td></tr>
<tr valign="top"><td width=70% bgcolor="aaaaaa"><font color="white" size="5">
    <H2>Headline</H2>
    data
</font></td>
<td width=30%>
    <h3>Current Time</h3>
    time
</td></tr>
</table>
</body>
</html>
Web page generated by test.html.

Figure 7.2. Web page generated by test.html.

To turn test.html into a Django template, you would replace the dynamic items Title, Headline, data, and time with the following variable placeholders, as shown in Listing 7.2:

{{ title}}, {{ headline }}, {{ data }} and {{time}}

Example 7.2. Full Contents of the Modified test.html File

<html xmlns="http://www.w3.org/1999/xhtml" lang="en-us" xml:lang="en-us" >
<head>
<title>{{ title }}</title>
</head>
<body>
<table width=100%>
<tr bgcolor="aabbcc"><td colspan="2">
<font size="12" color="white">{{ title }}</font>
</td></tr>
<tr valign="top"><td width=70% bgcolor="aaaaaa"><font color="white" size="5">
    <H2>{{ headline }}</H2>
    {{ data }}
</font></td>
<td width=30%>
    <h3>Current Time</h3>
    {{ time }}
</td></tr>
</table>
</body>
</html>

With the variable placeholders in the test.html file, Django enables you to deliver dynamic web pages based on different contexts. For example, the following code snippet creates a context that generates the web page shown in Figure 7.3:

c = Context()
c['title'] = 'My Log'
c['headline'] = 'Entry #5'
c['data'] = 'Found errors in subroutines 2, 5 and 8.'
from datetime import datetime
c['time'] = datetime.now()
Web page generated by context using the My Log code snippet.

Figure 7.3. Web page generated by context using the My Log code snippet.

To change the content that Django places in the web page, all that needs to happen is for the data in the context to change. For example, the following code snippet creates a context that generates the web page shown in Figure 7.4:

c = Context()
c['title'] = 'Corporate Memos'
c['headline'] = 'Company Party'
c['data'] = 'There will be a company Party on Friday. '
c['data'] += 'Families are invited.'
from datetime import datetime
c['time'] = datetime.now()

Web page generated by context using the Corporate Memos code snippet.

Figure 7.4. Web page generated by context using the Corporate Memos code snippet.

Accessing Objects Using HTML Templates

Django’s template parser allows you to access object fields directly from the template. This is a major advantage, because most of the data you will display in the web pages will be in the form of objects that were queried from the database. Instead of having to add each field as an entry in the Context dictionary, you only need to add the object.

Django uses the . (dot) syntax in the variable placeholder to access fields in the object. For example, to access the title field of a Blog object, you would use the following variable placeholder:

{{ blog.title }}

By the Way

If the value of the field is also an object, you can access the fields of the subobject as well. For example, if the Person object has a field blogs that refers to a list of Blog objects, you could access the title field of the first Blog object using the following syntax:

{{ person.blogs[0].name }}

Rendering a Template as an HTTP Response

In the preceding section, you learned how to create a Django template from an HTTP document. This section covers how to display it using the render_to_response() shortcut function. The render_to_response() function accepts the name of a template file and a dictionary as its only two arguments, as shown in the following example:

render_to_response('person_detail.html', {'p': person})

When you call render_to_response(), it opens the template file, reads the contents into a Template object, creates a Context object using the dictionary argument, renders the Template object based on the Context object, and outputs the results as an HttpResponse.

Did you Know?

You can use the locals() Python function to generate a dictionary containing all the locals in the current function context. Instead of building your own dictionary, you can just specify the locals() function in the render_to_response call:

render_to_response('person_detail.html', locals())

Extending Templates

As you build your website, you will need to create several different template files for different applications and views. This can result in a lot of redundant HTML code for headers, banners, and other content that will appear on several pages. Django provides the extends tag in its template engine to solve this problem.

The extends tag allows you to create a parent template file that will contain website elements that appear in more than one HTML view. Then, as you create templates for various views, you will only need to create content for that specific view in the view’s template. When the Django template parser encounters an extends tag, it parses the parent template first and then applies the child template.

The following text shows the syntax for enabling a view template to inherit from another template:

{% extends "site_base.html" %}

By the Way

The parent template, specified in quotation marks, is specified as a path relative to the paths defined in the TEMPLATE_DIRS setting in the settings.py file. If you defined c:website emplates in the TEMPLATE_DIRS setting and you create a parent template called c:website emplatessiteheader.html, you would use the following extends statement:

{% extends "site/header.html" %}

Did you Know?

You can specify a variable name instead of a filename in the extends tag. This allows you to dynamically control what the content will be by specifying different template filenames from within the view code.

You use block tags to control where items from the child template will be placed in the parent template. The block tags need to appear in both the parent and child templates. In the parent template, the block tags designate where data, with a block with the same name, from the child template will be placed. In the child template, the block tag is used to partition a section of data and assign it a name that can be referenced from the parent.

Blocks begin with a block tag and end with an endblock tag. The following code snippet shows the syntax for creating a block and assigning it the name content:

{% block content %}
<block code here>
{% endblock %}

The best way to show you how to extend a template is through an example. Listing 7.6 defines a basic parent template.

Example 7.6. A Basic Parent Template File, base.html

<html>
<head>
<title>{% block content %}Title{% endblock %}</title>
</head>
<body>
{% block content %}
Base Site
{% endblock %}
</body>
</html>

Listing 7.7 shows how to apply the parent template shown in Listing 7.6 in a child template.

Example 7.7. A Basic Child Template File, view.html

{% extends "base.html" %}
{% block title %}My Template View{% endblock %}
{%block content %}
<h1> My Web Page</h1><hr>
<li>Testing templates.</li>
{% endblock %}

When the view.html template shown in Listing 7.7 is parsed, the Django template parser sees the extends tag and parses the base.html parent template. Then, as it encounters the title and content blocks in the view.html file, it applies the HTML code in those sections to the HTTP response. Listing 7.8 shows the resulting HTML code that is sent as the HTTP response.

Example 7.8. Resulting HTML Response When view.html Extends base.html

<html>
<head>
<title> My Template View </title>
</head>
<body>
<h1> My Web Page</h1><hr>
<li>Testing templates.</li>
</body>
</html>

By the Way

If a no block in the child matches a block in the parent, the data contained in the block and endblock statements is added to the HTML response. For example, if we had not included the title block in Listing 7.7, the Django parser would have included the value contained in the title block of Listing 7.6, and the <title> HTML tag in Listing 7.8 would have been <title>Title</title>.

Embedding Templates

In addition to extending templates with parent templates, Django allows you to load the entire contents of a template into an existing template using the include tag. Unlike the extends tag, the include tag simply inserts the full contents of the specified template file into the existing template.

The include tag can be useful for creating “canned” components for your website, such as a calendar, that need to be displayed on several web pages.

For example, the following line of code embeds a template named comments.html into a template:

{% include "comments.html" %}

Did you Know?

You can specify a variable name instead of a filename in the include tag. This allows you to dynamically control what the content will be by specifying different template filenames from within the view code.

By the Way

Variables that are available in the view template also are available in templates that are embedded using the include tag.

Summary

In this hour, you learned how to configure Django to allow you to use HTML templates. You learned how to create template files and use them to enhance your views. You also learned how to create base templates that will reduce the amount of HTML code that is needed in your view templates. You also learned how to create templates for specific tasks and embed them into your view templates using the include tag.

Q&A

Q.

Is there a way to tie the templates into the Django admin interface?

A.

Yes. You can use the Django admin parent base_site.html in your view templates by using the following line of code to extend it:

{% extends 'admin/base_site.html' %}

Q.

Is there a way to render a template to a string object so that I can parse and possibly manipulate it?

A.

Yes. Django provides the django.template.loader.render_to_string (template_name, dictionary, context_instance) function that will render a template file to a string object. The render_to_string() function accepts a template file name as the first argument, a dictionary containing variables as an optional second argument, and a Context object as an optional third argument. The following code will render the someTemplate.html template file to a string:

from django.template.loader import render_to_string
render_to_string('someTemplate.html', {'name': 'Brad', 'pID': 1})

Workshop

The workshop consists of a set of questions and answers designed to solidify your understanding of the material covered in this hour. Try answering the questions before looking at the answers.

Quiz

1.

Where does Django begin looking for template files when they are specified in an extends or include command?

2.

Which tag should be used to embed another template file into an existing one?

3.

Which template file is parsed first—the parent or the child?

Quiz Answers

1.

It looks in the directories specified by the TEMPLATE_DIRS setting in the settings.py file.

2.

include.

3.

The child template.

Exercises

1.

Create an HTML template that displays a table of all Person objects in the database. The index() function of the iFriends/People/views.py file already generates the full HTML code. You will need to modify the file to generate the list as a string and add that string to the dictionary passed to render_to_response().

2.

Modify the template you created in Exercise 1 to extend the iFriends/templates/iFriends_base.html template.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.247.188