前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中。
|
1
2
3
4
|
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
|
尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么:
-
对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。
-
Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。
-
程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。
基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式,这就是本章要具体讨论的问题。
python的模板:HTML代码+模板语法
模版包括在使用时会被值替换掉的 变量,和控制模版逻辑的 标签。
def current_time(req): # ================================原始的视图函数 # import datetime # now=datetime.datetime.now() # html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now # ================================django模板修改的视图函数 # from django.template import Template,Context # now=datetime.datetime.now() # t=Template('<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>') # #t=get_template('current_datetime.html') # c=Context({'current_date':str(now)}) # html=t.render(c) # # return HttpResponse(html) #另一种写法(推荐) import datetime now=datetime.datetime.now() return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})
在 Django 模板中遍历复杂数据结构的关键是句点字符 .
语法:
语法:
|
1
|
{{var_name}} |
views:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def index(request):
import datetime
s="hello"
l=[111,222,333] # 列表
dic={"name":"yuan","age":18} # 字典
date = datetime.date(1993, 5, 2) # 日期对象
class Person(object):
def __init__(self,name):
self.name=name
person_yuan=Person("yuan") # 自定义类对象
person_egon=Person("egon")
person_alex=Person("alex")
person_list=[person_yuan,person_egon,person_alex]
return render(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list})
# return render(request,"index.html",locals()) |
template:
|
1
2
3
4
5
6
|
<h4>{{s}}</h4>
<h4>列表:{{ l.0 }}</h4>
<h4>列表:{{ l.2 }}</h4>
<h4>字典:{{ dic.name }}</h4>
<h4>日期:{{ date.year }}</h4>
<h4>类对象列表:{{ person_list.0.name }}</h4>
|
注意:句点符也可以用来引用对象的方法(无参数方法)。
|
1
|
<h4>字典:{{ dic.name.upper }}</h4>
|
模板之过滤器
语法:
|
1
|
{{obj|filter__name:param}} |
default
如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:
|
1
|
{{ value|default:"nothing" }}
|
length
返回值的长度。它对字符串和列表都起作用。例如:
|
1
|
{{ value|length }} |
如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如‘13 KB’,‘4.1 MB’,‘102 bytes’, 等等)。例如:
|
1
|
{{ value|filesizeformat }} |
如果 value 是 123456789,输出将会是 117.7 MB。
date
如果 value=datetime.datetime.now(),将返回当前时间的年-月-日格式
|
1
|
{{ value|date:"Y-m-d" }}
|
slice
如果 value="hello world",则结果为ello worl (也是顾头不顾尾)
|
1
|
{{ value|slice:"2:-1" }}
|
截断的字符串将以可翻译的省略号序列(“...”)结尾。(truncatewords则是按单词数目截断(单词与单词间按空格算),用法相同)
要截断的字符数
例如:
|
1
|
{{ value|truncatechars:3 }}
|
...”。
safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
|
1
|
value="<a href="">点击</a>"
|
|
1
|
{{ value|safe}} |
这里简单介绍一些常用的模板的过滤器,更多详见
模板之标签
标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。
一些标签需要开始和结束标签 (例如 {% tag %} ...标签 内容 ... {% endtag %})。
for标签
遍历每一个元素:
{% for person in person_list %} <p>{{ person.name }}</p> {% endfor %}
可以利用{% for obj in list reversed %}反向完成循环。
遍历一个字典:
{% for key,val in dic.items %} <p>{{ key }}:{{ val }}</p> {% endfor %}
注:循环序号可以通过{{forloop}}显示
forloop.counter #默认第一个循环的序号为1,升序 forloop.counter0 # 默认第一个循环的序号为0,升序 forloop.revcounter #循环序号为降序,最后一个为1 forloop.revcounter0 #循环序号为降序,最后一个为0 forloop.first #第一个为True,其余为False forloop.last #最后一个为True,其余为False