django 模版系统
一. 语法
{ { 变量 } }
{% 表达式 %}
二. 变量
{ {变量名} }
深度查询据点符( . )在模版语言中有特殊的含义. 当模版系统遇到点(.) 查询顺序如下:
1.字典查询
2.属性或方法的查询
3.数字索引查询
注意事项:
1.如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
2.如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为’’ (空字符串) 。
views.py
def index(request):
s = 'hello'
lst = [1,2,3]
dic = {"name":"tom","age":13}
return render(request,'index.html',{"s":s,"lst":lst,"dic":dic})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a>渲染的字符是{{ s }}</a>
<a>列表是{{ lst }}</a>
<a>字典中的name是{{ dic.name }}</a>
</body>
</html>
三.过滤器
Django的模版语言中,用过滤器来修改变量的显示
语法:
使用过滤器来改变变量的显示
{{ value|filter_name:参数 }}
value|default:"nothing" 默认值
value|length 返回值的长度
value|filesizeformat 将值格式化为一个可读的文件尺寸
value|slice:"1:2" 切片
value|date:"Y-m-d H:M:S" 格式化时间
value|safe 不用对value进行转义
value|truncatechars:9 截断字符串 这里的参数为9(6个字符串+3个省略号)
value|truncatewords 在一定数量的字后截断字符串, 是截多少个单词
value|cut:' ' 移除value中所有的与给出的变量相同的字符串
list|join:',' 就像python中的str.join(list)
blog_date|timesince:comment_date 将日期格式设为自该日期起的时间
conference_date|timeuntil:from_date 测量从开始直到给定日期或日期时间的时间
管道符“|”来应用过滤器,需要注意:
1.支持链式操作,一个过滤器的输出作为另一个过滤器的输入
2.可以接受参数,{{content|trunctewords:10}} 表示显示content的前10个词
3.参数若包含空格,必须用引号包裹,如{{list|join:’,’}}就是用逗号和空格连接一个列表中元素
4.’|’管道符左右两边没有空格
django的模版语言提供了许多的内置过滤器,常用的有
default
如果一个变量是false或者为空,使用给定的默认值.否则,使用变量的值.如果value没有传值或者值为空就会显示nothing
{{value|default:"nothing"}}
length
返回值的长度,作用于字符串和列表,如value = [’a’,’b’,’c’,’d’]的话,就显示4,因为列表的长度为4
{{value|length}}
filesizeformat
将值格式化为一个’人类可读的文件尺寸’,如(1GB,2.4MB等),如果value是len = 10511515,会显示10.0MB
{{value|filesizeformat}}
slice
切片,字符串或其他可切片的数据类型,冒号左边为开始的索引,右边为结束的索引,-1表示切到倒数第一个
{{value|slice:"2:-1"}}
date
格式化,如果value = datetime.datetime.now()
{{value|date:"Y-m-d H:i:s"}}
关于时间日期的可用参数有很多,可以google查询
safe
{{value|safe}}
django模版进行渲染时会对HTML标签和JS等语法标签自动转义,防止用户提交时使用js,html代码破坏(防止xss攻击).为了防止这些内容被转义,使用safe来告诉django这段代码是安全的不必转义
views.py
def safe(request):
s = '<a> 这里是a标签 </a>'
return render(request,'safe.html',{"s":s})
safe.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ s|safe }}
</body>
</html>
truncatechars
如果字符多于指定的字符数量,就会被阶段.截断后的字符串以可翻译的省略号序列(‘...’)结尾.
{{ value|truncatechars:9}}
结果显示的三个省略号也是9个字符内的,就是6个字符+3个省略号.可以配合前端的点击事件展开
truncatewords
在一定数量的字后截断字符串(截指定个数的单词),比如s = ’hello world’结果就是 hello ..…
{{value|truncatewords:3}}
cut
移除value张红所有的与给出的变量相同的字符串
{{value|cut:''}}
移除变量中所有的空格
join
使用字符串连接列表,{{list|join:’,’}}, 就像python中的str.join(list)
timesince
将日期格式设为自该日期起的时间(例如,“4天,6小时”)。
采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。 例如,如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回“8小时”:
{{ blog_date|timesince:comment_date }}
分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。
分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。
timeuntil
类似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间。 例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则{{ conference_date | timeuntil }}将返回“4周”。
使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2006年6月22日,则以下内容将返回“1周”:
{{ conference_date|timeuntil:from_date }}
四.标签Tags
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是循环器,通过点来使用功能
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
with..as:
{% with 变量名=变量.属性.属性.. %}
{{ 变量 }}
{% endwith %}
或:
{% with 变量.属性.属性.. as 变量名%}
{% endwith %}
for..…empty
for标签带有一个可选的{% empty %}从句,如果给出的组是空的或没有找到时,可以行操作
{% for person in person_list %}
<p>{{ person.name }}</p>
{% empty %}
<p>sorry,no person here</p>
{% endfor %}
if标签
{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
{% if num > 100 or num < 0 %}
<p>无效</p> <!--不满足条件,不会生成这个标签-->
{% elif num > 80 and num < 100 %}
<p>优良</p>
{% else %} <!--也是在if标签结构里面的-->
<p>及格</p>
{% endif %}
也可以只有if和else
{% if user_list|length > 5 %} <!--结合过滤器来使用-->
长度大于5
{% else %}
或者
{% endif %}
csrf_token
以post提交表单的时候,会报错,之前在settings文件中把配置注释了,本身不应该被注释掉,这个标签用于跨站请求伪造保护.在页面的form表单内(一定要写在form表单里面)的任合位置加:
{% csrf_token %}
这个用来对应验证是否是这个页面进行的提交
注释的写法:
{#...#}
其他:
- Django的模板语言不支持连续判断,即不支持以下写法:
{% if a > b > c %}
...
{% endif %}
- Django的模板语言中属性的优先级大于方法
def xx(request):
d = {"a": 1, "b": 2, "c": 3, "items": "100"}
return render(request, "xx.html", {"data": d})
如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:
{{ data.items }}
默认会取d的items key的值。
五.模版继承
可以创建一个基本的页面,还能定义被子模版覆盖的blocks,就是说有许多结构相同的页面,使用模版继承可以直接将母版的版式拿来使用,非常方便
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{%/span> endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
子模版代码:
{% extends "base.html" %} # 这句话一定要写在第一行
{% block title %}子模版{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
为了方便可以给{%endblock%}标签一个名字,例如:
{%block content%}
...
{%endblock content%}
不能在一个模版中定义多个相同名字的block标签
六.组件
可以将常用的页面内容,比如导航条,页头页尾这些组件保存在单独的文件中,然后再需要使用的地方,文件的任意位置按语法导入
{% include 'navbar.html' %}
组件.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color: red;
height: 40px;
}
</style>
</head>
<body>
<div class="c1">
<div>
<a href="">xx</a>
<a href="">dd</a>
</div>
</div>
</body>
</html>
嵌入的页面.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% include 'nav.html' %}
<h1>xxxxxxxxxx</h1>
</body>
</html>