FSD-Module 2
FSD-Module 2
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% else %}
<p>Get back to work.</p>
{% endif %}
In Python, the empty list ([]), tuple (()), dictionary ({}), string (''), zero (0), and the special
object None are False in a Boolean context. Everything else is True.
The {% if %} tag accepts and, or, or not for testing multiple variables, or to negate a given
variable.
Example:
{% if athlete_list and coach_list %}
Both athletes and coaches are available.
{% endif %}
{% if not athlete_list %}
There are no athletes.
{% endif %}
{% if athlete_list or coach_list %}
There are some athletes or some coaches.
{% endif %}
{% if %} tags don’t allow and and or clauses within the same tag, because the order of
logic would be ambiguous.
For example, this is invalid:
{% if athlete_list and coach_list or cheerleader_list %}
for
The {% for %} tag allows to loop over each item in a sequence. As in Python’s for
statement, the syntax is for X in Y, where Y is the sequence to loop over and X is the name of the
variable to use for a particular cycle of the loop. Each time through the loop, the template system
will render everything between {% for %} and {% endfor %}.
Example, use the following to display a list of athletes given a variable athlete_list:
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
ifequal/ifnotequal:
The {% ifequal %} tag compares two values and displays everything between {% ifequal
%} and {% endifequal %} if the values are equal.
This example compares the template variables user and currentuser:
{% ifequal user currentuser %}
<h1>Welcome!</h1>
{% endifequal %}
The arguments can be hard-coded strings, with either single or double quotes, so the
following is valid:
{% ifequal section 'sitenews' %}
<h1>Site News</h1>
{% endifequal %}
Only template variables, strings, integers, and decimal numbers are allowed as arguments
to {% ifequal %}.
Examples:
{% ifequal variable 1 %}
{% ifequal variable 1.23 %}
{% ifequal variable 'foo' %}
{% ifequal variable "foo" %}
Any other types of variables, such as Python dictionaries, lists, or Booleans, can’t be hardcoded in
{% ifequal %}.
Examples:
{% ifequal variable True %}
{% ifequal variable [1, 2, 3] %}
{% ifequal variable {'key': 'value'} %}
To test whether something is true or false, use the {% if %} tags instead of {% ifequal %}.
Comments:
To designate a comment, use {# #}:
{# This is a comment #}
The comment will not be output when the template is rendered.
A comment cannot span multiple lines. This limitation improves template parsing performance. In
the following template, the rendered output will look exactly the same as the template (i.e., the
comment tag will not be parsed as a comment):
This is a {# this is not
a comment #}
test.
Filters:
Template filters are simple ways of altering the value of variables before they’re displayed.
Filters: {{ name|lower }}
This displays the value of the {{ name }} variable after being filtered through the lower filter,
which converts text to lowercase. Use a pipe (|) to apply a filter.
Filters can be chained—the output of one filter is applied to the next.
A common idiom for escaping text contents and then converting line breaks to <p> tags:
{{ my_text|escape|linebreaks }}
Some filters take arguments.
A filter argument: {{ bio|truncatewords:"30" }}
This displays the first 30 words of the bio variable. Filter arguments are always in double
quotes.
Important Filters:
• addslashes: Adds a backslash before any backslash, single quote, or double quote. This
is useful if the produced text is included in a JavaScript string.
• date: Formats a date or datetime object according to a format string given in the
Parameter.
Example:
{{ pub_date|date:"F j, Y" }}
• escape: Escapes ampersands, quotes, and angle brackets in the given string. This is useful
for sanitizing user-submitted data and for ensuring data is valid XML or XHTML.
escape makes these conversions:
• Converts & to &
• Converts < to <
• Converts > to >
• Converts " (double quote) to "
• Converts ' (single quote) to '
• length: Returns the length of the value. Use this on a list or a string, or any Python
object that knows how to determine its length.
TEMPLATE LOADING:
Django provides a convenient and powerful API for loading templates from disk, with the
goal of removing redundancy both in the template-loading calls and in the templates themselves.
To use the template-loading API, first tell the framework where the templates is stored.
The place to do this is in the settings file.
A Django settings file is the place to put configuration of the Django instance (aka your
Django project). It’s a simple Python module with module-level variables, one for each setting.
django-admin.py startproject mysite
the script created a default settings file named settings.py.
The file contains variables that look like this,
DEBUG = True
TIME_ZONE = 'America/Chicago'
USE_I18N = True
ROOT_URLCONF = 'mysite.urls'
TEMPLATE_DIRS setting: This setting tells Django’s template-loading mechanism where to look
for templates. By default, it’s an empty tuple. Pick a directory where to store the templates and
add it to TEMPLATE_DIRS,
TEMPLATE_DIRS = (
'/home/django/mysite/templates',
)
➢ Can specify any directory, as long as the directory and templates within
that directory are readable by the user account under which the Web server runs.
Recommend creating a templates directory within the Django project
➢ Don’t forget the comma at the end of the template directory string! Python requires
commas within single-element tuples to disambiguate the tuple from a parenthetical
expression.
➢ It’s simplest to use absolute paths (directory paths that start at the root of the
filesystem).
import os.path
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\', '/'),
)
This example uses the “magic” Python variable __file__, which is automatically set to the
file name of the Python module in which the code lives.
TEMPLATE_DIRS = (
'C:/www/django/templates',
)
With TEMPLATE_DIRS set, the next step is to change the view code to use Django’s
template-loading functionality rather than hard-coding the template paths. Returning to the
current_datetime view,
Change it like,
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
t = get_template('current_datetime.html')
html = t.render(Context({'current_date': now}))
return HttpResponse(html)
The get_template() function takes a template name as its argument, figures out where the
template lives on the filesystem, opens that file, and returns a compiled Template object.
If get_template() cannot find the template with the given name, it raises a
TemplateDoesNotExist exception.
render_to_response()
To load a template, fill a Context, and return an HttpResponse object with the result of the
rendered template.
function called render_to_response(), which lives in the module django.shortcuts.
use render_to_response() rather than loading templates and creating Context and
HttpResponse objects manually.
current_datetime example rewritten to use render_to_response():
from django.shortcuts import render_to_response
import datetime
def current_datetime(request):
now = datetime.datetime.now()
return render_to_response('current_datetime.html', {'current_date': now})
Subdirectories in get_template()
Storing templates in subdirectories of the template directory is easy.
t = get_template('dateapp/current_datetime.html')
get_template(), just include the subdirectory name and a slash before the template name,
Windows users, be sure to use forward slashes rather than backslashes. get_template()
assumes a Unix-style file name designation.
{% include 'includes/nav.html' %}
This example includes the contents of the template includes/nav.html:
{% include template_name %}
This example includes the contents of the template whose name is contained in the variable
template_name.
TEMPLATE INHERITANCE:
Use Django’s template system to create entire HTML pages. This leads to a common Web
development problem: across a Web site, how do you reduce the duplication and redundancy of
common page areas, such as sitewide navigation?
A classic way of solving this problem is to use server-side includes, directives that can
embed within the HTML pages to “include” one Web page inside another. Indeed, Django supports
that approach, with the {% include %} template tag just described. But the preferred way of solving
this problem with Django is to use a more elegant strategy called template inheritance.
Template inheritance build a base “skeleton” template that contains all the common parts
of the site and defines “blocks” that child templates can override.
Example:
Consider current_datetime view, by editing the current_datetime.html file:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>The current time</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
<p>It is now {{ current_date }}.</p>
<hr>
<p>Thanks for visiting my site.</p>
</body>
</html>
what happens while creating a template for another view, say the hours_ahead view, want
to again make a nice, valid, full HTML template.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>Future time</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
<p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
<hr>
<p>Thanks for visiting my site.</p>
</body>
</html>
Just duplicated a lot of HTML.
The server-side include solution to this problem is to factor out the common bits in both templates
and save them in separate template snippets, which are then included in each template. Then store
the top bit of the template in a file called header.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
And perhaps you’d store the bottom bit in a file called footer.html:
<hr>
<p>Thanks for visiting my site.</p>
</body>
</html>
With an include-based strategy, headers and footers are easy.
In the above example, both pages feature a title—<h1>My helpful timestamp site</h1>—but
that title can’t fit into header.html because the <title> on both pages is different.
Django’s template inheritance system solves these problems. Instead of defining the snippets that
are common, define the snippets that are different.
The first step is to define a base template—a skeleton of the page that child templates will
later fill in.
Example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
{% block content %}{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
</body>
</html>
template tag: {% block %} tag.
All the {% block %} tags do is tell the template engine that a child template may override
those portions of the template.
For this base template, modify the existing current_datetime.html template to use it:
{% extends "base.html" %}
{% block title %}The current time{% endblock %}
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
Each template contains only the code that’s unique to that template. No redundancy needed. Want
to make a sitewide design change, just make the change to base.html, and all of the other templates
will immediately reflect the change.
Working Procedure:
While loading the template current_datetime.html, the template engine sees the {%
extends %} tag, noting that this template is a child template. The engine immediately loads the
parent template—in this case, base.html.
At that point, the template engine notices the three {% block %} tags in base.html and replaces
those blocks with the contents of the child template. So, the title defined in {% block title %} will
be used, as will the {% block content %}.
Note that since the child template doesn’t define the footer block, the template system uses the
value from the parent template instead. Content within a {% block %} tag in a parent template is
always used as a fallback.
Inheritance doesn’t affect the way the context works, and can use as many levels of
inheritance as needed.
One common way of using inheritance is the following three-level approach:
1. Create a base.html template that holds the main look and feel of your site. This is the
stuff that rarely, if ever, changes.
2. Create a base_SECTION.html template for each “section” of your site (e.g.,
base_photos.html and base_forum.html). These templates extend base.html and include
section-specific styles/design.
3. Create individual templates for each type of page, such as a forum page or a photo
gallery. These templates extend the appropriate section template.
This approach maximizes code reuse and makes it easy to add items to shared areas, such as
sectionwide navigation.