这篇主要讲述三方面:1.模板的基本标签;2.模板基本使用方法;3.句点变量的调用。
一个简单例子的模板:
<html>
<head><title>Ordering notice</title></head>
<body><h1>Ordering notice</h1>
<p>Dear {{ person_name }},</p>
<p>Thanks for placing an order from {{ company }}. It's scheduled to ship on {{ ship_date|date:"F j, Y" }}.</p>
<p>Here are the items you've ordered:</p><ul>
{% for item in item_list %}
<li>{{ item }}</li>
{% endfor %}
</ul>{% if ordered_warranty %}
<p>Your warranty information will be included in the packaging.</p>
{% else %}
<p>You didn't order a warranty, so you're on your own when the products inevitably stop working.</p>
{% endif %}<p>Sincerely,<br />{{ company }}</p>
</body>
</html>
归纳:
变量:
{{ person_name }}
for循环:
{% for item in item_list %}
<li>{{ item }}</li>
{% endfor %}
if判断:
{% if ordered_warranty %}
<p>Your warranty information will be included in the packaging.</p>
{% else %}
<p>You didn't order a warranty, so you're on your own when the products inevitably stop working.</p>
{% endif %}
过滤器:
{{ ship_date|date:"F j, Y" }}
如何使用模板系统:
一、最基本使用方式
>>> from django import template
>>> t = template.Template('My name is {{ name }}.')
>>> c = template.Context({'name': 'Adrian'})
>>> print t.render(c)
My name is Adrian.
>>> c = template.Context({'name': 'Fred'})
>>> print t.render(c)
My name is Fred.
# t.render(c)返回的值是一个Unicode对象,不是普通的Python字符串。
# 这就是使用Django模板系统的基本规则:写模板,创建 Template 对象,创建 Context , 调用 render() 方法。
同一模板,多个上下文,通过模板渲染多个context
>>> from django.template import Template, Context
>>> t = Template('Hello, {{ name }}')
>>> print t.render(Context({'name': 'John'}))
Hello, John
>>> print t.render(Context({'name': 'Julie'}))
Hello, Julie
>>> print t.render(Context({'name': 'Pat'}))
Hello, Pat
一个渲染方式
# Bad
for name in ('John', 'Julie', 'Pat'):
t = Template('Hello, {{ name }}')
print t.render(Context({'name': name}))
# Good
t = Template('Hello, {{ name }}')
for name in ('John', 'Julie', 'Pat'):
print t.render(Context({'name': name}))
二、深度变量的使用
上面的例子中,我们通过 context 传递的简单参数值主要是字符串,还有一个datetime.date 范例。然而,模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。
在 Django 模板中遍历复杂数据结构的关键是句点字符 (.)。
示例,访问字典的值:
>>> 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)
u'Sally is 43 years old.'
示例,访问date的年月日:
>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
1993
>>> d.month
5
>>> d.day
2
>>> t = Template('The month is {{ date.month }} and the year is {{date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
u'The month is 5 and the year is 1993.'
示例,访问类对象:
>>> 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)
u'Hello, John Smith.'
示例,调用引用对象的方法:
>>> from django.template import Template, Context
>>> t = Template('{{ var }} ‐‐ {{ var.upper }} ‐‐ {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
u'hello ‐‐ HELLO ‐‐ False'
>>> t.render(Context({'var': '123'}))
u'123 ‐‐ 123 ‐‐ True'
示例,访问列表索引:
>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
u'Item 2 is carrots.'
# 不允许使用负数列表索引。像 {{ items.‐1 }} 这样的模板变量将会引发`` TemplateSyntaxError``
归纳句点查找规则:
句点查找规则可概括为: 当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找:
1.字典类型查找 (比如 foo["bar"] )
2.属性查找 (比如 foo.bar )
3.方法调用 (比如 foo.bar() )
4.列表类型索引查找 (比如 foo[bar] )
系统使用找到的第一个有效类型。 这是一种短路逻辑。
示例,句点查找可以多级深度嵌套:
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name.upper }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
u'SALLY is 43 years old.'
示例,方法调用:(这个看不懂 以后再研究)
在方法查找过程中,如果某方法抛出一个异常,除非该异常有一个silent_variable_failure 属性并且值
为True ,否则的话它将被传播。如果异常被传播,模板里的指定变量会被置为空字符串,比如:
>>> t = Template("My name is {{ person.first_name }}.")
>>> class PersonClass3:
... def first_name(self):
... raise AssertionError, "foo"
>>> p = PersonClass3()
>>> t.render(Context({"person": p}))
Traceback (most recent call last):
...
AssertionError: foo
>>> class SilentAssertionError(AssertionError):
... silent_variable_failure = True
>>> class PersonClass4:
... def first_name(self):
... raise SilentAssertionError
>>> p = PersonClass4()
>>> t.render(Context({"person": p}))
u'My name is .'
仅在方法无需传入参数时,其调用才有效。否则,系统将会转移到下一个查找类型(列表索引查找)。
显然,有些方法是有副作用的,好的情况下允许模板系统访问它们可能只是干件蠢事,坏的情况下甚至会
引发安全漏洞。
例如,你的一个BankAccount 对象有一个 delete() 方法。 如果某个模板中包含了像
{{ account.delete }}这样的标签,其中account
又是BankAccount 的一个实例,请注意在这个模板
载入时,account对象将被删除。
要防止这样的事情发生,必须设置该方法的alters_data 函数属性:
def delete(self):
# Delete the account
delete.alters_data = True
模板系统不会执行任何以该方式进行标记的方法。接上面的例子,如果模板文件里包含了
{{ account.delete }} ,对象又具有 delete()方法,而且delete() 有alters_data=True这个属性,那么在
模板载入时, delete()方法将不会被执行。它将静静地错误退出。
多数时间,你可以通过传递一个完全填充(full populated)的字典给 Context() 来初始化 上下文(Context) 。
但是初始化以后,你也可以使用标准的Python字典语法(syntax)向上下文(Context)
对象添加或者删除条目:
>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c['foo']
'bar'
>>> del c['foo']
>>> c['foo']
Traceback (most recent call last):
...
KeyError: 'foo'
>>> c['newvariable'] = 'hello'
>>> c['newvariable']
'hello'
网友评论