Django——模板基础
每一个Web框架都需要一种很便利的方法用于动态生成HTML页面。 最常见的做法是使用模板。 模板包含所需HTML页面的静态部分,以及一些特殊的模版语法,用于将动态内容插入静态部分。 说白了,模板层就是如何往HTML文件中填入动态内容的系统。 模板的设计实现了业务逻辑view与显示内容template的分离,一个视图可以使用任意一个模板,一个模板可以供多个视图使用。 ?1.配置引擎Django可以配置一个或多个模板引擎(语言),也可以不用引擎。 Django自带一个称为DTL(Django Template Language )的模板语言,以及另外一种流行的Jinja2语言(需要提前安装,pip install Jinja2) 如果使用默认引擎,也不用配置什么,详细的配置,这里不做赘述,可以参考这个博客http://www.liujiangblog.com/course/django/144,或官方文档(英文允许的话)。 2模板语法—变量变量看起来就像是这样:? 当模版引擎遇到一个变量,它将从上下文context中获取这个变量的值,然后用值替换掉它本身。 变量的命名包括任何字母数字以及下划线("_")的组合。点(".")也有可能会在变量名中出现,不过它有特殊的含义。最重要的是,变量名称中不能有空格或标点符号。 当模版系统遇到点("."),它将以这样的顺序查询这个圆点具体代表的功能:
如果你使用的变量不存在,模版系统将插入 示例: 视图views.py class Book(object):
def __init__(self,title):
self.title=title
def test(request):
nums=[10,11,12]
info={‘name‘:‘Eric‘}
book=Book(‘长得帅如何与人相处‘)
context={‘nums‘:nums,‘info‘:info,‘book‘:‘book‘}
return render(request,‘test.html‘,context)
模板test.html <body> <h3>书的编号:{{ nums.0 }}</h3> <h3>书的作者:{{info.name }}</h3> <h3>书的名字:{{ book.title }}</h3> </body> ?注意:句点符也可以用来引用对象的方法(无参数方法): <h3>作者:{{ info.name.upper }}</h3> ? 3过滤器因为过滤器紧挨着变量,所以先说过滤器 过滤器看起来是这样的: 一些过滤器带有参数,过滤器参数包含空格的话,必须用引号包起来。例如,使用逗号和空格去连接一个列表中的元素,你需要使用 django内置的过滤器有很多,列举几个常用的: default 如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。 {{ value|default:"nothing" }} length返回值的长度。它对字符串和列表都起作用。 {{ value|length }} # 如果value是[‘a‘,‘b‘,‘c‘,‘d‘],那么输出4。 slice返回列表的一部分。也就是切片,与Python的列表切片相同的语法。 {{ some_list|slice:":2" }} # 如果some_list是[‘a‘, ‘b‘, ‘c‘] ,输出将为[‘a‘, ‘b‘]。 truncatechars如果字符串包含的字符总个数多于指定的字符数量,那么会被截断掉后面的部分。截断的字符串将以“...”结尾。 {{ value|truncatechars:9 }} # 如果value是Joel is a slug,输出为Joel i...。 date根据给定格式对一个日期变量进行格式化。 # 如果 value=datetime.datetime.now() {{ value|date:"Y-m-d" }} safeDjango的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如: value="<a href="">点击</a>" {{ value|safe}} 关于自动转义,我们后面再说。 4.标签标签看起来像是这样的:? 标签比变量复杂得多,有些用于在输出中创建文本,有些用于控制循环或判断逻辑,有些用于加载外部信息到模板中供以后的变量使用。 一些标签需要开始和结束标签(即? 同样,列举几个常用的: for标签# 循环对象中的每一个元素 <ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} </ul> # 如果循环对象points的每个元素都是(x,y)这样的二元元组,可以像以下面一样输出 {% for x,y in points %} There is a point at {{ x }},{{ y }} {% endfor %} 要访问一个字典中的键值,这个方法同样有用: {% for key,value in data.items %} {{ key }}: {{ value }} {% endfor %} 下面是Django为for标签内置的一些属性,可以当作变量一样使用
for ... emptyfor标签带有一个可选的 <ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% empty %} <li>Sorry,no athletes in this list.</li> {% endfor %} </ul> if标签
if标签可以使用not,and或or来测试布尔值 if标签允许使用这些操作符: {% if num > 100 or num < 0 %} <p>无效</p> {% elif num > 80 and num < 100 %} <p>优秀</p> {% else %} <p>凑活吧</p> {% endif %} include加载指定的模板并以标签内的参数渲染。这是一种引入别的模板的方法,include类似Python的import。 {% include "foo/bar.html" %} # 将子模版渲染并嵌入当前HTML中 url这是路由在模板层面反向解析用到的标签,返回与给定视图和可选参数匹配的绝对路径引用(不带域名的URL) {% url ‘some-url-name‘ v1 v2 %} # 第一个参数是url()的名字,其他参数是可选的并且以空格隔开,这些值会在URL中以参数的形式传递 如果使用urlconf的名称空间网址,通过冒号指定完全名称,如下所示: {% url ‘myapp:view-name‘ %} with使用一个简单地名字缓存一个复杂的变量,当你需要使用一个代价较大的方法(比如访问数据库)很多次的时候这是非常有用的。 {% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %} csrf_token这个标签用于跨站请求伪造保护 5.自定制标签、过滤器Django为我们提供了自定义的机制,可以通过使用Python代码,自定义标签和过滤器来扩展模板引擎,然后使用{% load %}标签。 5.1配置准备1.将要增加自定义标签的app在 2.在app中新建一个 3.要在模块内自定义标签,首先,这个模块必须包含一个名为 from django import template register = template.Library() 5.2自定义过滤器
因为第二步django已经帮我们完成,所以我们实际上只需要自己完成第一步和第三步 示例:定义一个自动省略字符的过滤器 # mytags.py from django import template register = template.Library() @register.filter(name=‘truncate_char‘) # 注册过滤器的装饰器,name属性可以省略 def truncate_char(value): # 定义过滤器的函数 if len(value) > 20: return value[0:20]+‘...‘ else: return value ? 然后在模板页面装载使用 {% load mytags %} 装载自定义过滤器 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {{ ‘超过20个字符后,将后面的字符省略,没超过20个字符,则可以显示全部‘|truncate_chars }} </body> </html> ? 5.3自定义标签自定义标签相对于自定义过滤器来说要复杂很多,因为自定义标签可以做任何事情! 自定义标签分为很多类型
5.3.1简单标签import datetime from django import template register = template.Library() @register.simple_tag def current_time(format_string): # 传入一个时间格式 return datetime.datetime.now().strftime(format_string) # 返回当前时间 ? Library.simple_tag(takes_context=True),takes_context=True参数可以让我们访问模板的当前环境上下文,即将当前环境上下文中的参数和值作为字典传入函数中的一个名为context的参数 @register.simple_tag(takes_context=True) def current_time(context,fromat_string): timezone = context[‘timezone‘] # 接收上下文参数 return your_get_current_time_method(timezone,format_string) ? 当使用take_context=True时,函数的第一个参数必需为context。也可以使用name参数对函数进行重命名。 5.3.2内含标签这种类型的标签可以被其他模板进行渲染,然后将渲染结果输出 Library.inclusion_tag()支持take_context=True,用法类似Library.simple_tag() from django import template register = template.Library() @register.inclusion_tag(‘result.html‘) def tset(): a=[‘first‘,‘second‘,‘third‘] return {‘choices‘: a} ? result.html <ul> {% for choice in choices %} <li> {{ choice }} </li> {% endfor %} </ul> ? ? test.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% load mytags %} # 装载自定义模块 {% test %} # 导入标签 </body> </html> ? 5.3.3分配标签类似于简单标签,但并不会输出结果,可以使用 as 关键字将结果赋给一个参数。 @register.assignment_tag def get_current_time(format_string): return datetime.datetime.now().strftime(format_string) ? {% get_current_time "%Y-%m-%d %I:%M %p" as the_time %} <p>The time is {{ the_time }}.</p> ? 6.模板继承Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让我们创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。 模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。 父模板如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。 block标签:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。 为了更好的可读性,建议给endblock标签写上名字,这个名字与对应的block名字相同。父模板中也可以使用上下文中传递过来的数据。 {% block 名称 %} 预留区域,可以编写默认内容,也可以没有默认内容 {% endblock %} 子模板extends标签:继承,写在子模板文件的第一行。 {% extends "父模板路径" %} 子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值。 {% block 名称 %} 实际填充内容 {{ block.super }} # 用于保留父模板中block的内容 {% endblock 名称 %} 示例父模板:base.html <html> <head> <title>{{title}}</title> </head> <body> <h2>这是头</h2> <hr> {%block content%} 这是内容,有默认值 {%endblock content%} <hr> {%block foot%} {%endblock foot%} <hr> <h2>这是尾</h2> </body> </html> ? 子模板:test.html {% extends "base.html" %}
{% block content %}
两个黄鹂鸣翠柳
我还没有女朋友
{{ block.super }}
{% endblock content %}
{% block foot %}
垂死病中惊坐起
笑问客从何处来
{% endblock foot %}
? ? 那么子模板的输出效果就是: <html> <head> <title>{{title}}</title> </head> <body> <h2>这是头</h2> <hr> 两个黄鹂鸣翠柳 我还没有女朋友 这是内容,有默认值 <hr> 垂死病中惊坐起 笑问客从何处来 <hr> <h2>这是尾</h2> </body> </html> ? 注意:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |