Django之模板层的实现代码
在例子视图中返回文本的方式有点特别,即HTML被直接硬编码在Python代码之中。
defcurrent_datetime(request): now=datetime.datetime.now() html="Itisnow%s."%now returnHttpResponse(html)
尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并是一个好主意。让我们来看一下为什么:
- 对页面设计进行的任何改变都必须对Python代码进行相应的修改。站点设计的修改往往比底层Python代码的修改要频繁得多,因此如果可以在不进行Python代码修改的情况下变更设计,将会方便很多。
- Python代码编写和HTML设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同的部门)来完成。设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。
- 程序员编写Python代码和设计人员制作模板两项工作过同时进行的额效率是最高的,远胜于让一个人等待另一个人完成对某个既包含Python又包含HTML的文件的编辑工作。
基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。我们可以使用Django的模板系统(TemplateSystem)来是现在这种模式,这就是本章要具体讨论的问题。
Python的模板:HTML代码+模板语法
defcurrent_time(req): #================================原始的视图函数 #importdatetime #now=datetime.datetime.now() #html="现在时刻:%s.
"%now #================================django模板修改的视图函数 #fromdjango.templateimportTemplate,Context #now=datetime.datetime.now() #t=Template('现在时刻是:{{current_date}}
') ##t=get_template('current_datetime.html') #c=Context({'current_date':str(now)}) #html=t.render(c) # #returnHttpResponse(html) #另一种写法(推荐) importdatetime now=datetime.datetime.now() returnrender(req,'current_datetime.html',{'current_date':str(now)[:19]})
一、模板语法之变量
在Django模板中遍历复杂数据结构的关键是句点字符,语法:
{{var_name}}
views.py:
defindex(request): importdatetime s="hello" l=[111,222,333]#列表 dic={"name":"yuan","age":18}#字典 date=datetime.date(1993,5,2)#日期对象 classPerson(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] returnrender(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list})
template:
{{s}}
列表:{{l.0}}
列表:{{l.2}}
字典:{{dic.name}}
日期:{{date.year}}
类对象列表:{{person_list.0.name}}
注:句点符也可以用来引用对象的方法(无参数方法):字典:{{dic.name.upper}}
二、模板之过滤器
语法:
{{obj|filter_name:param}}
default
如果一个变量是False后者为空,使用给定的默认值。否则,使用变量的值。例如:
{{value|default:'nothing'}}
length
返回值的长度。它对字符串和列表都起作用。例如:
{{value|length}}
如果value是 ['a','b','c','d'],那么输出的就是4.
filesizeformat
将值格式化为一个“人类可读的”文件尺寸(例如 '13KB', '4.1MB', '102bytes',等等)。例如:
{{value|filesizeformat}}
如果value=123456789,输出将会是117.7MB。
date
如果value=datetime.datetime.now()
{{value|date:"Y-m-d"}}
slice
如果value="helloworld"
{{value|slice:"2:-1"}}
truncatechars
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列("...")结尾。
参数:要截断的字符数
{{value|truncatechars:9}}
safe
Django的模板中会对HTML标签和JS语法等标签进行自动转义,原因显而易见这样是为了安全。但是有时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后他添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器"|safe"的方式告诉Django这段代码是安全的不必转义。比如:
value="点击" {{value|safe}}
三、模板之标签
标签看起来像是这样: {%tag%}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息的模板中。一些标签需要开开始和结束标签(例如 {%tag%}...标签内容...{%endtag%})。
for标签
遍历每一个元素:
可以利用 {%forobjinlistreversed%}方向完成循环。
遍历一个字典:
{%forkey,valindic.items%}{{key}}:{{val}}
{%endfor%}
注:循环序号可以通过 {{for|loop}}显示
forloop.counter#Thecurrentiterationoftheloop(1-indexed) forloop.counter0#Thecurrentiterationoftheloop(0-indexed) forloop.revcounter#Thenumberofiterationsfromtheendoftheloop(1-indexed) forloop.revcounter0#Thenumberofiterationsfromtheendoftheloop(0-indexed) forloop.first#Trueifthisisthefirsttimethroughtheloop forloop.last#Trueifthisisthelasttimethroughtheloop for...empty
for标签带有一个可选的 {%empty%}从句,以便在给出的组是空的或者没有被找到时,可以有所操作。
{%forpersoninperson_list%}{{person.name}}
{%empty%}sorry,nopersonhere
{%endfor%}
if标签
{%if%}会对一个变量求值,如果它的值是True(存在、不为空、且不是boolean类型的False值),对应的内容块会输出。
{%ifnum>100ornum<0%}无效
{%elifnum>80andnum<100%}优秀
{%else%}凑活吧
{%endif%}
with标签
使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵”的方法(比如访问数据库)很多次的时候是非常有用的。例如:
{%withtotal=business.employees.count%} {{total}}employee{{total|pluralize}} {%endwith%}
csrf_token标签
这个标签用于跨站请求伪造保护。
四、自定义标签和过滤器
1、在settings中的INSTALLED_APPS配置当前app,不然Django无法找到自定义的simple_tag。
2、在app中创建templatetags模块(模块名只能是templatetags)。
3、创建任意.py文件,如:my_tags.py。
fromdjangoimporttemplate fromdjango.utils.safestringimportmark_safe register=template.Library()#register的名字是固定的,不可改变 @register.filter deffilter_multi(v1,v2): returnv1*v2
@register.simple_tag defsimple_tag_multi(v1,v2): returnv1*v2
@register.simple_tag defmy_input(id,arg): result=""%(id,arg,) returnmark_safe(result)
4、在使用自定义simple_tag和filter的HTML文件中导入之前创建的my_tags.py。
{%loadmy_tags%}
5、使用simple_tag和filter(如何调用)
-------------------------------.html {%loadxxx%} #num=12 {{num|filter_multi:2}}#24 {{num|filter_multi:"[22,333,4444]"}} {%simple_tag_multi25%}参数不限,但不能放在iffor语句中 {%simple_tag_multinum5%} 注:filter可以用在if等语句后,simpe_tag不可以。 {%ifnum|filter_multi:30>100%} {{num|filter_multi:30}} {%endif%}
五、模板继承(extend)
Django模板引擎中最强大也是最复杂的部分就是模板继承了。模板继承可以让你创建一个基本的“骨架”模板,它包含你站点中的全部元素,并且可以定义能够被子模板覆盖的blocks.
通过从下面这个例子开始,可以容易地理解模板继承:
{%blocktitle%}Myamazingsite{%/span>endblock%} {%blocksidebar%} {%endblock%}
Home Blog