The Definitive Guide To Django 2 学习笔记(七) 第四章 模板 (三)使用模板系统

接下来,我们开始学习如何使用模板系统,但我们并不和前面说的View相结合,我们的这里的目的是展示模板系统是如何独立于Django框架运行的。下面是在pyhon代码中使用Django模板系统的基础例子:

1.通过提供原生文本代码创建Template模板对象

2.调用Template对象的render()方法并传入所给的参数(上下文文本)。

>>> 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.

创建模板对象

最简单的创建Template对象的方法就是直接实例化一个出来。Template类在Django.Template module里,构造函数需要一个参数,原生template 代码。接下来我们将一步步看看在python交互解释器中是如何工作的。

 

在myiste项目中,输入 python manage.py shell 启动交互解释器。

(原文中此处解释了为什么没有使用python而是使用了python shell,主要是此处使用python shell 方便了配置。)

 

一个简单的例子:

>>> from django.template import Template

>>> t = Template('My name is {{ name }}.')

>>> print t

你会在显示中看到:

<django.template.Template object at 0xb7d5f24c>

0xb7d5f24c 每次都是不一样的,但他们是有关系的,是python用来识别Template对象的标识。

调用模板

一旦你创建模板完毕,你可以通过把数据传给一个context然后传给模板,context是一个简单的模板变量的合集,它包含了模板中变量的值。

context是django.template module中的值。它的构造函数包括一个参数,字典映射变量给值。调用Template对象的render()方法来填充模板。、:

>>> from django.template import Context, Template

>>> t = Template('My name is {{ name }}.')

>>> c = Context({'name': 'Stephane'})

>>> t.render(c)

u'My name is Stephane.'

多上下文,多模板

一旦你创建了Template对象,你可以给它赋予多个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

不论什么时候你这样使用模板,创建模板对象一次,然后显示它们多次比较有效率:

# 坏的编码

for name in ('John', 'Julie', 'Pat'):

t = Template('Hello, {{ name }}')

print t.render(Context({'name': name}))
# 好的编码

t = Template('Hello, {{ name }}')

for name in ('John', 'Julie', 'Pat'):

print t.render(Context({'name': name}))

 上下文变量查找

之前的例子中,我们都是把简单的变量传递给了上下文Context,实际上,模板系统还可以处理更为复杂的数据类型。

>>> 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.'

同样,我们可以使用自定义类:

>>> 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.'

 点通常也可以指代对象的方法,例如,python中的string类型的对象有upper()和isdigit()方法。如下:

>>> 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'

注意,在调用方法的时候不需要外面的括号,也不可以向方法传递参数,你只可以调用无参方法。

最后,点还可以用来访问list中的序列,如下:

>>> 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异常。

方法调用行为

方法调用要比其他类型的查找稍微复杂一些,下面是一些需要记住的:

如果在查找方法期间,方法执行过程中出现了异常,异常将会被弹出来,除非异常拥有silent_variable_failure标记而且该标记为true.如果异常拥有silent_variable_failure标记,变量将会被赋予空字符,如下例:

>>> 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 .'

1.方法调用只在方法不需要参数的时候起作用,否则,系统将会移动到下一个查找类型。

2.显示,有些方法会有一些副作用,安全漏洞,允许模板系统访问他们。

   譬如,有一个BankAccount类型的对象,该对象有个delete()方法。如果模板系统包括类似的语句{{account.delete}},account是一个BankAccount类型的对象,该对象会被展示模板时被删除。

   为了防止对象被删除,给方法添加一个alters_data的标记:

def delete(self):

# Delete the account

delete.alters_data = True

模板系统不会执行任何被这样标记了的方法,在这个例子中,展示模板时,delete()方法不会被执行,取而代之的是静默的失败。

无效的变量如何被处理

默认情况下,如果变量在模板系统中不存在,将返回空字符串,静默地失败。考虑下面的例子:

>>> from django.template import Template, Context

>>> t = Template('Your name is {{ name }}.')

>>> t.render(Context())

u'Your name is .'

>>> t.render(Context({'var': 'hello'}))

u'Your name is .'

>>> t.render(Context({'NAME': 'hello'}))

u'Your name is .'

>>> t.render(Context({'Name': 'hello'}))

u'Your name is .'

系统静默地失败而非抛出异常是因为要平滑地处理异常,上面的例子中,所有的查找失败都是因为变量大小写错误或是名字不对,在现实世界中,仅仅因为这样的错误而使网站不可访问时不可接受的。

上下文对象

多数情况下你将会实例化一个Context对象,利用pythong字典的特性,你可以在创建了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'

 

你可能感兴趣的:(django)