Context Variable: Dot Lookup
$ python manage.py shell
- 1 dict
>>> from django.template import Template, Context
>>>
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
'Sally is 43 years old.'
- 2 attribute
>>> from django.template import Template, Context
>>>
>>> class Person(object):
... def __init__(self, first_name, last_name):
... self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
'Hello, John Smith.'
- 3 Method
It’s not possible to pass arguments to the methods. You can only call methods that have no required arguments.
>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
'123 -- 123 -- True'
- 4 list
Negative list indices are not allowed. For example, the template variable
{{ items.-1 }} would cause a
TemplateSyntaxError`.
>>> from django.template import Template, Context
>>>
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
'Item 2 is carrots.'
- 5 Invalid Variables
Generally, if a variable doesn’t exist, the template system inserts the value of the engine’s
string_if_invalid
configuration option, which is an empty string by default.
>>> from django.template import Template, Context
>>>
>>> t = Template('Your name is {{ name }}.')
>>> t.render(Context())
'Your name is .'
>>> t.render(Context({'var': 'hello'}))
'Your name is .'
- Dot lookup
Dot lookups can be summarized like this: when the template system encounters a dot in a variable name, it tries the following lookups, in this order:- Dictionary lookup (e.g.,
foo["bar"]
) - Attribute lookup (e.g.,
foo.bar
) - Method call (e.g.,
foo.bar()
) - List-index lookup (e.g.,
foo[2]
)
- Dictionary lookup (e.g.,
Tags
- 1 if-else
{% if ... %}
...
{% elif ... %}
...
{% else %}
...
{% endif %}
Use of actual parentheses in the
if
tag is invalid syntax.
- 2 for
{% for x in y_list %}
...
{% empty %}
...
{% endfor %}
the
for
tag supports an optional{% empty %}
clause that lets you define what to output if the list is empty.
-
3 forloop
forloop.counter
is always set to an integer representing the number of times the loop has been entered. This is one-indexed, so the first time through the loop, forloop.counter will be set to 1.forloop.counter0
is like forloop.counter, except it’s zero-indexed. Its value will be set to 0 the first time through the loop.forloop.revcounter
is always set to an integer representing the number of remaining items in the loop. The first time through the loop,forloop.revcounter
will be set to the total number of items in the sequence you’re traversing. The last time through the loop,forloop.revcounter
will be set to 1.forloop.revcounter0
is likeforloop.revcounter
, except it’s zero-indexed. The first time through the loop,forloop.revcounter0
will be set to the number of elements in the sequence minus 1. The last time through the loop, it will be set to 0.forloop.first
is a Boolean value set toTrue
if this is the first time through the loop.forloop.last
is a Boolean value set toTrue
if this is the last time through the loop.forloop.parentloop
is a reference to the forloop object for the parent loop, in case of nested loops.
4 comments
{# ... #} // one-line
{% comment %} //multi-line
...
...
{% endcomment %}
filters
A filter argument comes after a colon and is always in double quotes.
{{ name|lower }}
Templates in views
- 1
settings.py
setDIRS
to[os.path.join(BASE_DIR,'templates')]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
# ...
- 2 create a \templates directory inside your root \mypro folder.
\mypro
\mypro
\templates
manage.py
- 3 views.py
from django.template.loader import get_template
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
t = get_template('current_datetime.html')
html = t.render({'current_date': now})
return HttpResponse(html)
or
from django.shortcuts import render
import datetime
def current_datetime(request):
now = datetime.datetime.now()
return render(request, 'current_datetime.html', {'current_date': now})
- 4 current_datetime.html
<html>
<body>
It is now {{ current_date }}
</body>
</html>
- 5 runserver
- 6 Template Inheritance
base.html
<!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>
current_datetime.html
{% extends "base.html" %}
{% block title %}The current time{% endblock %}
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
hours_ahead.html
{% extends "base.html" %}
{% block title %}Future time{% endblock %}
{% block content %}
<p>
In {{ hour_offset }} hour(s), it will be {{ next_time }}.
</p>
{% endblock %}