模板标签
1、前面那篇文章中介绍了使用context参数进行传参,使HTML页面拥有了一定的动态效果。同时也提到了DTL模板中不仅可以有HTML标签对,还可以可以有if判断、for循环等。if、for等语句(模板标签)在HTML模板中就是以一种特殊的标签对形式存在的
2、html的数据是静态的,动态内容由框架标签负责引进。Django在html页面嵌入标签,是以{% 代码块 %}的形式,而输出内容使用{{ 变量名称 }}的形式进行接收
3、模板中"{% %}"形式的代码是Django模板语言的函数语法,Django模板函数需要结束标签。如,{%for%}循环的结束标签是{%endfor%}
标签释义
1、模板标签的本质是函数,标签名一般即为函数名。主要作用是载入代码渲染模板或对传递过来的参数进行一定的逻辑判断或计算后返回
2、模板中"{% %}"形式的代码是Django模板语言的函数语法,Django模板函数需要结束标签。如,{%for%}循环的结束标签是{%endfor%}
3、在Web框架中,标签常分为内置标签和自定义标签,在内置标签不够用的时候,才会去自定义标签(说了句废话)。Django的内置标签不是很多,好好熟悉一番
常用的模板标签
if标签
1、if标签相当于Python中的if语句,是进行条件判断用的。同样也有elif和else相对应。只是说在模板语法中所有的标签都需要使用标签符号"{%%}"进行包裹
2、使用{%if%}、{%elif%}、{%else%}、{%endif%}进行条件判定,使用方法和Python中相同:{%if%}标签可以单独使用,可以有{%else%}、{%endif%}标签,也可以没有
⑴在模板语言中如果有{%if%}开始标签,那么就必须要有{%endif%}结束标签:因为在Python中语句的结束是用缩进来表示的,但是在模板语法中是没有缩进的,因此代码不知道你什么时候该结束if标签,因此使用了{%endif%}来表示if标签的结束
⑵另,在模板语法中不管是哪个标签,都是:只要有开始标签,就必须有结束标签(url标签除外,该标签没有结束标签)
3、if中可以使用:==、!=、<=、<、>=、>、in、not in、is、is not等判断运算符。另外还可以使用and、or等关键字来表示逻辑关系
例1:一般字典
⑴编辑视图
定义一个字典,并将其赋值给context参数
⑵编辑模板
1、在模板中使用if标签,对context传过来的值进行判断,根据判断来确定最终显示的数据
⑶访问
例1_1:嵌套字典
⑴编辑视图
⑵编辑模板
例1_2:值为列表
⑴编辑视图
⑵编辑模板:这里也可以使用people.索引数对列表中的元素进行取值
注:从上面例子可以看出
1、所有的标签都在"{% %}"之间
2、在获取参数值时,获取的方式跟我们前面那篇文章介绍的方法一致:可以直接使用键名,也可以使用'.'点操作符(只是这里不需要在使用{{ }}来包裹键名了)
3、总的来说,if标签对的语法为:
{% if 参数+条件 %}
满足if条件时执行的语句
{% elif 参数+条件 %}
满足elif条件时执行的语句
{% else %}
满足else条件时执行的语句
{% endif %}
for...in...标签
1、for...in...标签:类似于Python中的for...in...循环。可以遍历列表、元组、字符串、字典等一切可以遍历对象
2、使用{% for variable in variables %}...{% endfor%}来对字典、列表、字符串、元组等进行遍历
3、在遍历字典时需要使用item、keys、values的时候可以直接用点'.'的方式调用:执行方法的时候不能使用圆括号
4、另在for...in...标签中还支持其他一些特殊方法:
方法 | 说明 |
{%for variable in variables reversed %} | 反向遍历时可以使用 |
forloop.counter | 可以显示这是第几次遍历,默认从1开始 |
forloop.counter0 | 显示当前是第几次遍历,从0开始 |
forloop.revcounter | 反向显示是第几次遍历,最后一个为1 |
forloop.revcounter0 | 反向显示是第几次遍历,最后一个为0 |
forloop.first | 是否是第一次遍历 |
forloop.last | 是否是最后一次遍历 |
例2:正序遍历
⑴编辑视图
⑵编辑模板
⑶访问
例2_1:反向遍历,就是从最后一个元素开始遍历
例2_2:使用字典方法
⑴编辑视图
⑵编辑模板
⑶访问
例2_3:
⑴编辑视图
⑵编辑模板
⑶访问
例2_4:forloop.counter
这个例子中的视图与例2_3一样,只是在模板中增加了一列
⑴编辑模板
⑵访问
注:
1、forloop.counter0与forloop.counter的作用差不多的,只是或一个事从0开始,一个是从1开始的
2、与上个例子中一样:forloop.revcounter和forloop.revcounter0的输出也差不多,只是说是将序号反过来了的
例2_5:
这个例子中的视图与例2_3一样,只是在for标签中增加了if标签:根据循环次数来确定背景颜色
⑴编辑模板
⑵访问
for...in...empty标签
这个标签的使用方式、适用场景跟for...in标签差不多,只不过这个标签是:如果在遍历的对象没有任何元素的情况下,会执行empty中的内容
例3:遍历对象有元素时
⑴编辑视图
⑵编辑模板
⑶访问
例3_1:遍历对象无元素时
⑴编辑视图
⑵访问
模板根上个例子一样
注:
1、在DTL模板语法中,for标签是没有continue和break语句的(这个是跟Python语法不一样的)
2、根据上面几个例子,在模板语法中,总的for标签语法大概为:
{% for 遍历出的变量 in 待遍历对象 %}
{{ 接收遍历出来的变量 }}并执行对应语句
{% empty %}
遍历对象无元素的处理
{% endfor %}
with标签
1、在Python语法中,我们可以在任意位置定义任意类型的变量,但是在DTL模板语法中就不能随意定义变量了,但实际中又可能需要在模板中定义变量,因此就有了with标签了
2、With标签:用于在模板中定义变量
3、有时候在模板中访问一个参数的时候比较复杂,那么就可以先把这个复杂的参数缓存(赋值)到一个变量上,以后就可以直接使用这个变量了
4、需要注意的就是:使用with标签定义的变量只能在with标签块中使用:即,只能在{% with %}...{% endwith %}之间使用
5、with标签定义变量一共有两种方式
⑴{% with 值 as 参数名 %}:这种方式是Django中默认的方式
⑵{% with 参数名=值 %}:在使用这种方式定义变量的时候,不能在等号左右两边留有空格
例4:
⑴编辑视图
⑵编辑模板
⑶访问
例4_1:
⑴编辑视图
⑵编辑模板
⑶访问
注:从上面的例子中,可以看出
with标签对的作用是:将从视图函数(context参数)中获取的参数赋值给一个变量,后面如果要使用这个参数时,就可以直接使用前面定义的变量了。获取参数的方式根前面介绍的一样。只是说这个变量只能在with标签对中使用
url标签
1、在模板中,我们经常要写一些URL,比如某个a标签中需要定义href属性。当然如果通过硬编码的方式直接将这个url写死在模板里面也是可以的,但是这样做的话对以后项目维护可能不是一件好事。因此建议使用反转的方式来实现,类似于Django视图中的reverse()函数一样
⑴reverse()函数:用于反转URL,即通过URL名字来找到对应的URL。如,reverse(login:'login'),其表示应用(实例)命名空间login下的名为login的URL。reverse()函数用于视图函数中,使用场景比如对前端请求的URL参数进行判断,如果无某些参数的话,就跳转到另一页面
⑵URL标签对:也是用于反转URL,即通过URL名字来找到对应的URL。如,<a href="{% url book:'list' %}">图书列表页面</a>,其表示应用(实例)命名空间book下的名为list的URL。url标签用于模板中,使用场景比如某个链接按钮,在点击后跳转到另一页面
⑶django模板中url标签和view中的reverse()功能相同,都是通过制定处理视图来返回一个url
⑷使用url标签和reverse()函数,可以避免在模板和view中对url进行硬编码,这样即使url改变了,对模板和view也没有影响
2、如果URL反转的时候需要传递参数(传递URL参数),那么可以在后面传递。但是参数分为位置参数和关键字参数。位置参数和关键字参数不能同时使用
3、如果想要在使用url标签反转的时候,需要传递查询字符串的参数时,那么必须要手动在后面添加
4、如果需要传递多个参数,那么可以通过空格的方式进行分割
例5:使用url相对路径跳转
⑴编辑视图
⑵编辑模板
⑶访问
注:从上面的例子可以看出
1、在模板中使用URL跳转的时候,如果要将URL写成相对路径的话,就必须从根URLconf中的url参数开始写,也可以写成完整的URL路径(IP、端口、完整的URL参数),反正不能只写子URLconf部分
2、不过在模板中写URL的绝对路径是不明智的
⑴因为这是一个相对(完整的绝对路径不存在)的链接,在不同网页中打开可能会返回不一样的结果
⑵最重要的还是:如果在urls.py中修改了某个页面的地址,那么所有的地方(views.py和template中)都要修改
3、在使用相对路劲的话,URL第一个参数前必须加斜杠"/"。不然拼接出来的URL会与预期不一致
4、html链接的绝对路径:
⑴完整的一个路径就是绝对路径,即包含schema://host[:port#]/path/.../[?query-string][#anchor]
⑵例:http://news.sina.com.cn/world/
5、html链接的相对路径
⑴第一个字符为斜杠/:例:“/hello”, 这种会自动帮你添加你的协议名+域名+端口, 假设你的前一节为http://www.baidu.com:8000, 系统会自动匹配为"http://www.baidu.com:8000/hello" (我们实际情况中一般使用这种,因此就是前面说的相对路径需要从根URLconf段开始写)
⑵第一个字符不带斜杠:例:“hello”, 这种会在当前url中path段往后添加,假设你当前路径http://www.baidu.com:8000/hello, 系统会自动匹配为“http://www.baidu.com:8000/hello/hello
例5_1:使用URL名字进行跳转
⑴编辑视图
⑵编辑模板
⑶访问
注:从上面例子可以看出
1、使用url标签和url名字进行跳转就方便了很多,规避了后期项目维护的一部分问题(修改URL等)。格式为:{% url 'url名字' %},url名字需要用引号包裹
2、这个例子还有一个问题,也是在介绍reverse()函数时介绍过的,就是:万一URL名字重复,在直接使用URL名字进行跳转时,就有可能出现跳转错误的问题。因此更好的是加上url的命名空间
例5_2:使用URL名字进行跳转_命名空间
⑴编辑视图
⑵编辑模板
注:
1、上面只介绍了使用应用命名空间的使用,实例应用命名空间的使用跟上面例子一样。只需要将应用命名空间改成实例命名空间就可以了
2、自己的编写的时候发现:如果定义了应用命名空间,但是在模板HTML中使用url标签时没有加上应用命名空间的话,会报错。所以在实际中最好定义命名空间和在模板中使用命名空间,一步到位
例5_3:URL传递参数静态
⑴编辑视图
⑵编辑模板
例5_4:URL传递参数动态
⑴编辑视图
⑵编辑模板
注:从上面例子可以看出
1、在url标签中如果需要传递url参数的话,可以将值写死,也可以将值写成一个变量(通过context参数获取)
2、URL中存在多个参数时,直接在第一个参数后面加就可以了:{% url 'polls:page_detail' page_id='3' id='1'%}
3、上面这个例子中感觉逻辑应该是:在访问index页面时,就应该获得的page_id的值,然后用于跳转到page_detail页面,而不是说在跳转page_detail页面时才从page_detail视图中获得page_id的值,再用于跳转
例5_5:查询字符串的方式获取参数
⑴编辑视图
⑵编辑模板
⑶访问
注:
1、查询字符串不区分请求方式,客户端GET,POST方式的请求,都可以通过request.GET获取请求中的查询字符串数据
2、这种以查询字符串的方式传递参数中,如何将参数定义成一个可变的变量,目前还不知道该怎么定义
autoescape标签
1、作用:开启和关闭这个标签内元素的自动转义功能
2、自动转义是可以将一些特殊字符。比如将" < "转义成HTML语法能识别的字符
3、DTL中默认开启了自动转义。会将那些特殊字符进行转义。比如会将"<"转义成"<"
4、如果你不知道自己在干什么,最好是使用DTL的自动转义。这样网站才不容易出现XSS漏洞
5、如果变量确实是可信任的,那么可以使用"autoescape"标签来关闭自动转义
例6:
⑴编辑视图
⑵编辑模板
⑶访问
verbatim标签
1、默认在DTL模板中是会去解析那些特殊字符的。比如{%和%}以及{{等。如果在某个代码片段中不想使用DTL的解析引擎,那么可以将这个代码片段放在verbatim标签中
2、在实际生产中,我们可能会在模板中使用到多种模板引擎。比如两种模板引擎定义变量的方式都是{{变量名}},某个变量属于引擎1,因此就希望引擎2不会对这个变量进行解析。这个时候就需要用到这个标签了(将不需要解析的变量放到verbatim标签)
例7:
⑴编辑视图
⑵编辑模板
⑶访问