django html5模板,Django模板系统(非常详细)

The Django Book:第4章 Django模板系统

revised by xin_wang

前面的章节我们看到如何在视图中返回HTML,但是HTML是硬编码在Python代码中的

这会导致几个问题:

1,显然,任何页面的改动会牵扯到Python代码的改动

网站的设计改动会比Python代码改动更频繁,所以如果我们将两者分离开会更方便

2,其次,写后台Python代码与设计HTML是不同的工作,更专业的Web开发应该将两者分开

页面设计者和HTML/CSS程序员不应该编辑Python代码,他们应该与HTML打交道

3,程序员写Python代码同时页面设计者写HTML模板会更高效,而不是一个人等待另一个人编辑同样的文件

因此,使用Django的模板系统分离设计和Python代码会更干净更易维护

模板系统基础

Django模板是一个string文本,它用来分离一个文档的展现和数据

模板定义了placeholder和表示多种逻辑的tags来规定文档如何展现

通常模板用来输出HTML,但是Django模板也能生成其它基于文本的形式

让我们来看看一个简单的模板例子:

Ordering notice

Dear { { person_name }},

Thanks for placing an order from { { company }}. It's scheduled to

ship on { { ship_date|date:"F j, Y" }}.

Here are the items you've ordered:

{% for item in item_list %}

{ { item }}

{% endfor %}

{% if ordered_warranty %}

Your warranty information will be included in the packaging.

{% endif %}

Sincerely,
{ { company }}

这个模板本质上是HTML,但是夹杂了一些变量和模板标签:

1,用{ {}}包围的是变量,如{ {person_name}},这表示把给定变量的值插入,如何指定这些变量的值我们即将说明

2,用{%%}包围的是块标签,如{%if ordered_warranty%}

块标签的含义很丰富,它告诉模板系统做一些事情

在这个例子模板中包含两个块标签:for标签表现为一个简单的循环结构,让你按顺序遍历每条数据

if标签则表现为逻辑的if语句

在这里,上面的标签检查ordered_warranty变量的值是否为True

如果是True,模板系统会显示{%if ordered_warranty%}和{%endif%}之间的内容

否则,模板系统不会显示这些内容

模板系统也支持{%else%}等其它逻辑语句

3,上面还有一个过滤器的例子,过滤器是改变变量显示的方式

上面的例子中{ {ship_date|date:"F j, Y"}}把ship_date变量传递给过滤器

并给date过滤器传递了一个参数“F j, Y”,date过滤器以给定参数的形式格式化日期

类似于Unix,过滤器使用管道字符“|”

Django模板支持多种内建的块标签,并且你可以写你自己的标签

使用模板系统

在Python代码中使用模板系统,请按照下面的步骤:

1,用模板代码创建一个Template对象

Django也提供指定模板文件路径的方式创建Template对象

2,使用一些给定变量context调用Template对象的render()方法

这将返回一个完全渲染的模板,它是一个string,其中所有的变量和块标签都会根据context得到值

创建模板对象

最简单的方式是直接初始化它,Template类在django.template模块中,初始化方法需要一个参数

下面进入Python交互环境看看:

>>> from django.template import Template

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

>>> print t

你将看到如下信息

0xb7d5f24c每次都会改变,但是无所谓,它是Template对象的Python“identity”

在这本书中,我们会在Python的交互式会话环境中展示一些示例。当你看到三个大于号'>>>',就可以确定是在交互环境中了。

如果你从本书中拷贝代码,记得不要拷贝这些大于号。

当你创建Template对象,模板系统会编译模板代码,并准备渲染

如果你的模板代码有语法错误,调用Template()方法会触发TemplateSyntaxError异常

>>> from django.template import Template

>>> t = Template('{%notatag%}')

Traceback (most recent call last):

File "", line 1, in ?

...

django.template.TemplateSyntaxError: Invalid block tag: 'notatag'

系统触发TemplateSyntaxError异常可能出于以下情况:

1,不合法的块标签

2,合法块标签接受不合法的参数

3,不合法的过滤器

4,合法过滤器接受不合法的参数

5,不合法的模板语法

6,块标签没关

渲染模板

一旦你拥有一个Template对象,你可以通过给一个context来给它传递数据

context是一个变量及赋予的值的集合,模板使用它来得到变量的值,或者对于块标签求值

这个context由django.template模块的Context类表示

它的初始化函数有一个可选的参数:一个映射变量名和变量值的字典

通过context调用Template对象的render()方法来填充模板,例如:

>>> from django.template import Context, Template

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

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

>>> t.render(c)

'My name is Stephane.'

变量名必须以字母(A-Z或a-z)开始,可以包含数字,下划线和小数点,变量名大小写敏感

下面是一个模板编译和渲染的例子,使用这章开始时的模板例子:

>>> from django.template import Template, Context

>>> raw_template = """

Dear { { person_name }},

...

...

Thanks for ordering { { product }} from { { company }}. It's scheduled to

... ship on { { ship_date|date:"F j, Y" }}.

...

... {% if ordered_warranty %}

...

Your warranty information will be included in the packaging.

... {% endif %}

...

...

Sincerely,
{ { company }}

"""

>>> t = Template(raw_template)

>>> import datetime

>>> c = Context({'person_name': 'John Smith',

... 'product': 'Super Lawn Mower',

... 'company': 'Outdoor Equipment',

... 'ship_date': datetime.date(2009, 4, 2),

... 'ordered_warranty': True})

>>> t.render(c)

"

Dear John Smith,

\n\n

Thanks for ordering Super Lawn Mower from Outdoor Equipment.

It's scheduled to ship on April 2, 2009.

\n\n

Your warranty information will be included

in the packaging.

\n\n\n

Sincerely,
Outdoor Equipment

"

让我们来看看都做了些什么:

1,我们import Template和Context类,它们都在django.template模块里面

2,我们把模板文本存储在raw_template变量里,我们使用"""来构建string,它可以跨越多行

3,我们创建模板对象t,并给Template类的初始化函数传递raw_template变量

4,我们从Python的标准库import datetime模块,下面会用到它

5,我们创建一个context对象c,它的初始化函数使用一个映射变量名和变量值的字典

例如我们指定person_name的值为'John Smith',product的值为'Super Lawn Mower'等等

6,最后,我们调用模板对象的render()方法,参数为context对象c

这将返回渲染后的模板,将模板中的变量值替换并计算块标签的结果

如果你刚接触Python,你可能会问为什么输出中包含了新行字符'\n'而不是换行

这是因为Python交互环境中调用t.render(c)会显示string的representation而不是string的值

如果你想看到换行而不是'\n',使用print t.render(c)即可

上面是使用Django模板系统的基础,只是创建一个模板对象和context对象然后调用render()方法

同一个模板,多个context的情况:

一旦你创建了一个模板对象,你可以渲染多个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

无论何时,你使用同一个模板来渲染多个context的话,创建一次Template对象然后调用render()多次会更高效

# 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}))

Django的模板解析非常快,在后台,大部分的解析通过一个单独的对正则表达式的调用来做

这与基于XML的模板引擎形成鲜明对比,XML解析器比Django的模板渲染系统慢很多

Context变量查找

上面的例子中,我们给模板context传递了简单的值,大部分是string,以及一个datetime.date

尽管如此,模板系统优雅的处理更复杂的数据结构,如列表,字典和自定义对象

在Django模板系统中处理复杂数据结构的关键是使用(.)字符

使用小数点来得到字典的key,属性,对象的索引和方法

下面通过例子来解释,通过(.)访问字典的key:

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

通过(.)来访问对象的属性:

>>> 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})

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值