一.语法
关于模板渲染你只需要记两种特殊符号(语法):
{{ }}和 {% %}
变量相关的用{{}},逻辑相关的用{%%}。
二.变量
- 在Django的模板语言中按此语法使用:{{ 变量名 }}。
- 当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。 变量的命名包括任何字母数字以及下划线 ("_")的组合。
变量名称中不能有空格或标点符号。 - 深度查询据点符(.)在模板语言中有特殊的含义。当模版系统遇到点("."),它将以这样的顺序查询:
字典查询(Dictionary lookup)
属性或方法查询(Attribute or method lookup)
数字索引查询(Numeric index lookup)
示例:
views.py:
def index1(request):
num = 10
name = '张三'
name_list = ['李四','王五']
dic = {'name':'test','age':23,'hoby':'girl'}
class Person:
def __init__(self):
self.name = 'dog'
def dream(self):
return 'dreamer'
a = Person() #返回一个对象
return render(request,'index1.html',{'num':num,'name':name,'name_list':name_list,'dic':dic,'a':a})
# return render(request,'index.html',locals())
#locals()获取函数内容所有的变量,然后通过render方法给了index.html文件进行模板渲染,如果你图省事,你可以用它,但是很多多余的变量也被传进去了,效率低
index1.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>模板</h1>
<p>{{ num }}</p>
<p>{{ name }}</p>
<p>{{ name_list }}</p>
<p>{{ name_list.0 }}</p>
<p>{{ dic }}</p>
<p>{{ dic.age }}</p>
<p>{{ a.name }}</p>
</body>
</html>
三.过滤器
在Django的模板语言中,通过使用 过滤器 来改变变量的显示。
过滤器的语法: {{ value|filter_name:参数 }}
使用管道符"|"来应用过滤器。
例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。
注意事项:
- 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
- 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
- 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:’, ’ }}
- '|'左右没有空格没有空格没有空格
Django的模板语言中提供了大约六十个内置过滤器。
length
返回值的长度,作用于字符串和列表。
{{ name_list|length }}
default
如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值。
{{ xx|default:'啥也没有' }} #没有xx这个值就显示【啥也没有】
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 ‘13 KB’, ‘4.1 MB’, ‘102 bytes’, 等等)。例如:
movesizi = 123342224
{{ movesizi|filesizeformat }} #结果:117.6 MB
slice
切片,如果 value=“hello world”,还有其他可切片的数据类型
name = 'zhangsan'
{{ name|slice:'0:3' }} #zha
date
格式化,如果 value=datetime.datetime.now()
格式化,如果 value=datetime.datetime.now()
{{ now|date:'Y-m-d' }} #2020-03-12 不加date:March 12, 2020, 2:19 p.m.
truncatechars
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“…”)结尾。参数:截断的字符数
words = 'i love you my girl'
{{ words|truncatechars:'9' }} #结果:i love... 点也算在内
truncatewords
在一定数量的字后截断字符串,是截多少个单词。
例如:‘hello girl hi baby yue ma’,
{{ words1|truncatewords:'3' }} #结果:hello girl hi ...
cut
移除value中所有的与给出的变量相同的字符串
words1 = 'hello girl hi baby yue ma'
{{ words1|cut:' ' }} #移除空格 结果:hellogirlhibabyyuema
join
使用字符串连接列表,{{ list|join:’, ’ }},就像Python的str.join(list)
name_list = ['李四','王五']
{{ name_list|join:'*' }} #以星号连接 结果:李四*王五
safe
Django的模板中在进行模板渲染的时候会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全,django担心这是用户添加的数据,比如如果有人给你评论的时候写了一段js代码,这个评论一提交,js代码就执行啦,这样你是不是可以搞一些坏事儿了,这叫做xss攻击,所以浏览器不让你这么搞,给你转义了。但是有的时候我们可能不希望这些HTML元素被转义,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。
我们去network那个地方看看,浏览器看到的都是渲染之后的结果,通过network的response的那个部分可以看到,这个a标签全部是特殊符号包裹起来的,并不是一个标签,这都是django搞得事情。
使用safe之后,允许HTML元素被转义,这个时候就是一个正常的a标签了:
四.标签Tags
标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} …标签 内容 … {% endtag %})。
for标签
遍历每一个元素: 写个for,然后 tab键自动生成for循环的结构,循环很基础,就这么简单的用,没有什么break之类的,复杂一些的功能,你要通过js
列表:
<ul>
{% for name in name_list %}
<li>{{ name }}</li>
{% endfor %}
</ul>
字典:
<ol>
{% for key,value in dic.items %} #和Python里面一样 这里可以循环key,values
<li>{{ key }}-----{{ value }}</li>
{% endfor %}
</ol>
循环序号:
注:循环序号可以通过{{forloop}}显示,必须在循环内部用
forloop.counter 当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
forloop.parentloop示例:
d2 = [[11,22],[33,44]]
<ol>
{% for dd2 in d2 %}
<li>
{% for ddd2 in dd2 %}
{{ forloop.parentloop.counter }}
{{ forloop.counter}}
<a href="">{{ ddd2 }}</a>
{% endfor %}
</li>
{% endfor %}
</ol>
结果:
1 1 11 1 2 22
2 1 33 2 2 44
解释:
父层循环里面有两个元素,第一次循环计数是1,内部循环里面两个值,第一次打印11 第二次打印22 计数分别为1和2
父层循环里面有两个元素,第一次循环计数是2,内部循环里面两个值,第一次打印33 第二次打印44 计数分别为1和2
for … empty
for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。
<ul>
{% for foo in d3 %}
<li>{{ foo }}</li>
{% empty %}
<li>什么也没有</li>
{% endfor %}
</ul>
if 标签
{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。
{% if num > 100 %}
<a href="">大于100</a>
{% elif num < 100 %}
<a href="">小于100</a>
{% endif %}
还可以加过滤器:
{% if name_list|length > 3%}
<a href="">大于3</a>
{% elif name_list|length < 3%}
<a href="">小于3</a>
{% else %}
<a href="">等于3</a>
{% endif %}
with
使用一个简单地名字缓存一个复杂的变量,多用于给一个复杂的变量起别名,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的注意等号左右不要加空格。
<p>{{ dic.name }}</p>
第一种写法:
{% with shitai=dic.name %}
<h2>{{ shitai }}</h2>
{% endwith %}
第二种写法(as:类似与起别名):
{% with dic.name as shitai %}
<h2>{{ shitai }}</h2>
{% endwith %}
以上标签注意事项:
1. Django的模板语言不支持连续判断,即不支持以下写法:
{% if a > b > c %}
...
{% endif %}
2. 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的值。并不是itemsl方法。
csrf_token
我们以post方式提交表单的时候,会报错,还记得我们在settings里面的中间件配置里面把一个csrf的防御机制给注销了啊,本身不应该注销的,而是应该学会怎么使用它,并且不让自己的操作被forbiden,通过这个东西就能搞定。
这个标签用于跨站请求伪造保护,
五.模板继承
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
示例:
母版页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.nav{
background-color: red;
height: 40px;
}
.left_menu{
background-color: green;
color: white;
width: 20%;
height: 400px;
float: left;
}
.content{
width: 80%;
float: right;
}
.clearfix{
content: '';
display: block;
clear: both;
}
</style>
</head>
<body>
<div class="nav">
<a href="">22</a>
<a href="">23</a>
<a href="">24</a>
<input type="text"><button>搜索</button>
</div>
<div class="clearfix">
<div class="left_menu">
<ul>
<li><a href="{% url 'app02:menu1' %}">菜单1</a></li>
<li><a href="{% url 'app02:menu2' %}">菜单2</a></li>
<li><a href="{% url 'app02:menu3' %}">菜单3</a></li>
</ul>
</div>
<div class="content">
{% block content %}
母版页面
{% endblock %}
</div>
</div>
</body>
</html>
{% extends 'object.html' %} #继承母版页面
{% block content %} #预留的钩子 用来修改内容
{{ block.super }} #显示父类的内容
首页
{% endblock %}
{% extends 'object.html' %}
{% block content %}
菜单3
{% endblock %}
{% extends 'object.html' %}
{% block content %}
菜单2
{% endblock %}
{% extends 'object.html' %}
{% block content %}
菜单1
{% endblock %}
这里是使用继承的一些提示:
- 如果你在模版中使用 {% extends %}标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作,模板渲染的时候django都不知道你在干啥。
- 在base模版中设置越多的 {% block %}标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。
- 如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %} 中。
来源:CSDN
作者:猫鱼薄荷_她
链接:https://blog.csdn.net/qq_39253370/article/details/104817457