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': ''}
>>> 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': ''}))
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'
The Definitive Guide To Django 2 学习笔记(七) 第四章 模板 (三)使用模板系统的更多相关文章
- The Definitive Guide To Django 2 学习笔记(六) 第四章 模板 (二)使用模板系统
模板系统不是django特有的,它是python的一个库,你可以在任何地方使用它. 使用方法: 1.使用 Template()方法创建Template对象.2.调用Template对象的render( ...
- The Definitive Guide To Django 2 学习笔记(九) 第五章 模型 (一)数据库访问
以MySql数据库为例,先到http://dev.mysql.com/downloads/connector/python/处下载MysqlConnector for python的连接器. from ...
- The Definitive Guide To Django 2 学习笔记(八) 第四章 模板 (四)基本的模板标签和过滤器
标签 下面的部分概述了常见的Django标签. if/else {%if%} 标签 对一个变量值进行测试,如果结果为true,系统将会显示在{%if%} 和 {%endif%}之间的一切,看个例子: ...
- The Definitive Guide To Django 2 学习笔记(五) 第四章 模板 (一)基本模板系统
引入模板系统的原因,view中引入硬编码并非明智的选择,设计上的任何改变都会需要改动代码.python代码和HTML代码应该分开,这是多数Web站点的共识,分开会提高效率. 基本模板系统 Django ...
- The Definitive Guide To Django 2 学习笔记(四) 动态URLs
前面的例子中,虽然时间是动态可变的,但它的URL却是静态的(/time/).很多时候,URL也是需要动态改变,然后展示出不通的内容来.现在我们就来创建一个可以动态改变URL的例子. 如果URLconf ...
- The Definitive Guide To Django 2 学习笔记(二) 第二个View 动态内容
“Hello World”只是简单的展现了Django 基本的工作机制,但它不是动态的网页.第二个View我们将创建一个动态的网页,该页面上将展现当前的时间和日期. 该View需要做两件事,第一,计算 ...
- The Definitive Guide To Django 2 学习笔记(一) Views and UrL confsRL
1.如何找到django在Ubuntu下的安装路径: 进入python命令行,import django,print(django.__path__) 2.使用django-admin.py 创建项目 ...
- The Definitive Guide To Django 2 学习笔记(三) URLconfs 和松耦合
前面的例子体现了一个设计模式中的重要思想,松耦合. 不论我们是将/time/改成/current_time/,还是新建一个/another-time-page/同样指向views.py中的 curre ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第四章:Direct 3D初始化 学习目标 对Direct 3D编程在 ...
随机推荐
- 如何Oracle查出一个用户具有的所有系统权限和对象权限
1. 系统权限 SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE = 'LCAM_SYS_1216' UNION ALL SELECT * FROM DBA_SYS_ ...
- python利用opencv去除水印方法
OpenCV(Open Source Computer Vision Library)是一个跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法 在python中可以利用opencv来去除 ...
- 解析PHP中如何将数组变量写入文件
在用PHP记录日志,或者是 Ajax 请求出错想要 debug 的时候.我们一般都会将信息写入到一个指定的文件当中.然后根据相应的信息来处理问题.比如笔者最喜欢在用 Ajax 取不到数据的时候,在PH ...
- js怎么获取图片的相对地址
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content ...
- ActiveMQ订阅模式持久化实现
实现步骤:1.配置发送xml,applicationContext-send.xml <?xml version="1.0" encoding="UTF-8&quo ...
- Solidworks如何自动打开和关闭特征识别FeatureWorks
如果直接对已有的零件识别特征,可能会报错 删除多余的特征,先只保留一个输入(注意没有必要连草图也删掉,草图不会影响识别特征,你识别完了之后草图再接着该拉伸拉伸,该切除切除),然后再次执行识别特征, ...
- Unity3.5 GameCenter基础教程(转载)
原地址: http://forum.unity3d.com/threads/116901-Game-Center-Support/page3 using UnityEngine; using Unit ...
- ES6 字符串扩展
1.字符串遍历接口 字符串可以被for...of循环遍历 'use strict'; for (let codePoint of 'foo') { //控制台输出f o o console.log(c ...
- iOS UITableView表视图滚动隐藏UINavigationController导航栏
UITableView 继承于UIScrollView 所以UIScrollView 的代理方法相同适用于UITableView 中 隐藏导航栏的方法为: self.navigationControl ...
- Intellij idea 快键键
1.快速进入实现类: Command + Alt+B 2.全局查找: Shift + Shift 3.类继承关系: Ctrl + H 4.在继承层次上跳转则用 Command + B / Comman ...