- 一、模板介绍
- 二、变量
-
三 、过滤器
- 常用过滤器
-
四、标签Tags
- for 标签
- if 标签
- with 标签
- csrf_token 标签
-
五、自定义过滤器和标签
- 自定义过滤器
- 自定义标签
-
六 、模板继承
- 模板继承之include标签
- 模板继承之extends标签、block标签
- 七、静态文件配置
一 、模板介绍
Django的模板 = HTML代码 + 模板语法
存放在templates目录下的HTML文件就称为模板文件,如果我们想要返回 的HTML文件中的数据是动态的,那么就必须在HTML文件中嵌入变量 ,这就会用到Django的模板语法。
二、变量
在Django的模板语言中的变量语法:
View:{ ' HTML变量名 ' : ‘ views变量名 ’ }
HTML:{{ 变量名 }}
views.py 文件
from django.shortcuts import render import time def index(request): times = time.time() name = '小杨' name_list = ['小杨', '艾伦', '鲍勃'] info_dict = {'name': '小杨', 'age': 18, 'job': '攻城狮'} class A: def __init__(self, hobby): self.hobby = hobby def func(self): return self.hobby # 也可以传入对象 Bob = A('攻城狮') # 将数据传递给 index.html 文件进行渲染在发送给浏览器 return render(request, 'index.html', {'times': times, 'Bob': Bob, 'name': name, 'name_list': name_list, 'info_dict': info_dict})
index.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- 接收数据进行渲染 --> <p>{{ times }}</p> <p>{{ name }}</p> <p>{{ name_list.2 }}</p> <!-- 取列表中索引为2的数据 --> <p>{{ info_dict.age }}</p> <!-- 取字典中键值为age的数据 --> <p>{{ Bob.func }}</p> <!-- 执行对象中的方法返回数据 --> </body> </html>
三、过滤器
过滤器类似于python的内置函数,用来把视图传入的变量加以修饰后在显示
过滤器的语法:{{ 变量名|过滤器 : 可选参数 }}
注意事项:
- 过滤器支持“ 链式 ” 操作 。
- 过滤器参数包含空格需要用引号包裹起来。
- '|' 左右没有空格
常用过滤器
default
如果一个变量是false或者是空,就使用给定的默认值。否则 ,使用变量的值 。
{{ value|default:"默认值" }}
length
返回值的长度,主要用于字符串和列表。
{{ value|length }}
filesizeformat
将值的格式转换为一个可读的,主要用于显示文件大小
如果 value 是 123456789 ,输出将会是 117.7 MB。
{{ value|filesizeformat }}
slice
切片
{{ value|slice:"2:4" }}
date
格式化,若value = datetime.datetime.now()
{{ value|date:"Y-m-d H:i:s" }}
safe
转义,若value是一串代码 ,就可以对其进行转义成非代码的,防止xss攻击 。
{{ value|safe }}
truncatechars
如果字符串的字符个数多于指定的字符数量,那么就会被截断。截断的字符串将以可翻译的序号(...)结尾
{{ value|truncatechars:'6' }} # 后面的三个省略号也算在6个字符里面
truncatewords
在一定数量的字后截断字符串 ,是截多少个单词。
{{ value|truncatewords:2 }}
cut
移除value中所有的与给出的变量相同的字符串
{{ value|cut:'移除的字符' }}
join
使用字符串连接列表 。
{{ list|join:', ' }}
四 、标签Tags
标签是为了在模板中完成一些特殊功能,语法为{% 标签名 %} ,一些标签还需要搭配结束标签 {% endtag %}
for 标签
1、遍历每一个元素
{% for food in foods_list %} <p>{{ food }}</p> {% endfor %}
2、可以利用{% for obj in list reversed %}反向循环。
{% for food in foods_list reversed %} <p>{{ food }}</p> {% endfor %}
3 、遍历一个字典
{% for k, v in f_dict.items %} <p>{{ k }}:{{ v }}</p> {% endfor %}
for ... empty
可选的{ % empty % } 从句,给出的组是空的或者没有被找到时,执行的操作
{% for food in foods_list %} <p>{{ food }}</p> {% empty %} <p>没有foods_list ,或者foods_list为空</p> {% endfor %}
for循环的其他方法
forloop.counter 当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能 forloop.counter0 当前循环的索引值(从0开始) forloop.revcounter 当前循环的倒序索引值(从1开始) forloop.revcounter0 当前循环的倒序索引值(从0开始) forloop.first 当前循环是不是第一次循环(布尔值) forloop.last 当前循环是不是最后一次循环(布尔值) forloop.parentloop 本层循环的外层循环的对象 ,再通过上面的几个属性来显示外层循环的计数等 forloop.parentloop.counter
if 标签
对一个变量求值,如果它的值是“True ” (存在,不为空 ,且不是boolean类型的False值),对应的内容块会输出。
if语句支持 and 、or、==、> 、<、!=、<= 、>=、in、not in 、is、is not判断,注意条件两边都有空格 。
{% if num > 100 or num < 0 %} <p>条件1满足</p> <!--不满足条件 ,不会生成这个标签--> {% elif num > 80 and num < 100 %} <p>条件1不满足,条件2满足</p> {% else %} <!--也是在if标签结构里面的--> <p>条件都不成立,执行我吧</p> {% endif %}
with 标签
给一个复杂的变量起别名
{% with total=business.employees.count %} {{ total }} <!--只能在with语句体内用--> {% endwith %} 或者 {% with business.employees.count as total %} {{ total }} {% endwith %}
csrf_token 标签
用于跨站请求伪造保护
在form表单里面任何位置写上 。
工作原理:
1、在GET请求到form表单时 ,标签{% csrf_token%}会被渲染成一个隐藏的input标签 ,该标签包含了由服务端生成的一串随机字符串,如下:
<input type="hidden" name="csrfmiddlewaretoken" value="dmFo...O5">
2 、在使用form表单提交POST请求时,会提交上述随机字符串 ,服务端在接收到该POST请求时会对比该随机字符串,对比成功则处理该POST请求,否则拒绝 ,以此来确定客户端的身份
实例:
<form action="" method="post"> {% csrf_token %} 用户名:<input type="text"> 密码:<input type="password"> <input type="submit"> </form>
五、自定义过滤器和标签
当内置的过滤器和标签无法支持我们的需求时,就使用自定义标签或过滤器
自定义过滤器
步骤:
1、在文件夹app01中创建子文件夹 templatetags (文件夹只能是templatetags)
2 、在 templatetags 新建任意 .py 文件,如 mytags.py ,在该文件中自定义过滤器或标签。
内容如下
# mytags.py 文件 from django import template # 导入的模块 register = template.Library() # register 固定的名字 注册器 # 自定义过滤器 @register.filter def my_filter1(v1): # 不带参数的 # 对 v1 的操作 v = v1 + '操作' return v """ 使用:HTML文件中 {% load 文件名 %} --> 在HTML文档中必须先加载存有自定义过滤器和标签的文件 {{ value1|my_filter1 }} --> 无参数 把 value1 的值传入给 v1 ,做处理后返回。 """ @register.filter def my_filter2(v1, v2): # 带参数的过滤器(最多只能带两个) # 对 v1 v2 的操作 v = v1 + v2 return v """ 使用:HTML文件中 {% load 文件名 %} --> 在HTML文档中必须先加载存有自定义过滤器和标签的文件 {{ value1|my_filter1:value2 }} --> 有参数 把 value1 的值传给 v1 ,参数 value2 传给 v2 ,做处理后返回 """
自定义标签
步骤和自定义过滤器一样:
# mytags.py 文件 from django import template # 导入的模块 register = template.Library() # register 固定的名字 注册器 @register.simple_tag def my_tag(v1, v2, v3): # 自定义的标签可以定义多个参数 # 对传入的参数处理 v = v1 + v2 + v3 return v """使用:HTML文件中 {% load 文件名 %} --> 在HTML文档中必须先加载存有自定义过滤器和标签的文件 {% my_tag value1 value2 value3 %} 把 value1=v1 value2=v2 value3=v3 传入标签中,处理后返回 。 """
六 、模板继承
在Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的 “骨架” 模版,它包含您站点中的全部元素 ,并且可以定义能够被子模版覆盖的 blocks 。
模板主要围绕三种标签的使用:include标签、extends标签、block标签 。
模板继承之include标签
include标签也称为组件
组件和插件的简单区别:
- 组件是提供某一完整功能的模块。
- 而插件更倾向于封闭某一功能方法的函数。
作用:在一个HTML模板文件中 ,引入或者重复使用另一个模板文件的内容 。
{% include '模板名称' %}
实例:
把整个 test.html 模板引入到 index.html 模板中
<!-- test.html 文件 --> <div> <ul> <li>小杨</li> <li>小明</li> <li>鲍勃</li> <li>艾伦</li> </ul> </div> <!------------------------------------------------------------------------> <!-- index.html 文件 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> {% include 'test.html' %} <!-- 此处,当此文件发送给客户端的时候,就变成了test.html文件的内容了 --> </div> </body> </html>
模板继承之extends标签 、block标签
作用:在一个HTML模板文件中 ,引入或者重复使用另一个模板文件的内容。
include 有的功能 extends 全都有,但是 extends 可以搭配一个block标签,用于在继承的基础上增加新的内容
模板制定钩子
{% block 钩子名 %} <!-- 另一HTML模板引入此模板时可以从此处填充自己的内容 --> {% endblock 钩子名 %}
新模板引入旧模板 ,并从旧模板钩子处填充新内容
{% extends '模板名' %} <!-- 用新内容完全覆盖了父模板钩子中的内容 --> {% block 钩子名 %} <p> Hello World... </p> {% endblock 钩子名 %}
实例:
1、制定一个模板 base.html ,它定义了一个页面上面的导航栏,和页面左边的菜单栏 ,网页中间由我们引入模板时自行填充自己的内容。
|---------------------| | 导航栏 | |-------|-------------| | 菜 | | | 单 | 自行填充的内容 | | 栏 | | |-------|-------------|
模板 base.html 文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .top { height: 100px; background-color: red; } .left { height: 400px; width: 20%; background-color: aqua; float: left; } .centre { float: right; height: 400px; width: 80%; background-color: green; } </style> </head> <body> <div class="top"> <a href="">导航一</a> <a href="">导航二</a> <a href="">导航三</a> <a href="">导航四</a> </div> <div class="counter"> <div class="left"> <p><a href="">菜单一</a></p> <p><a href="">菜单二</a></p> <p><a href="">菜单三</a></p> <p><a href="">菜单四</a></p> </div> <div class="centre"> {% block centent %} <ul> <li>信息1</li> <li>信息2</li> <li>信息3</li> </ul> <!-- 另一HTML模板引入此模板时可以从此处填充自己的内容 --> {% endblock centent %} </div> </div> </body> </html>
2、index.html 模板引入base.html 模板,并在 base.html 模板钩子处添加新内容 。
{% extends 'base.html' %} {% block centent %} {{ block.super }} ————> 该变量会将父模板中 centent 中原来的内容继承过来 <!--在继承父模板内容的基础上新增的标签--> <form action="" method="post"> {% csrf_token %} 用户名:<input type="text"> 密码:<input type="password"> <input type="submit"> </form> {% endblock centent %}
3 、当启动 Django 访问 index.html 页面时返回的内容如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .top { height: 100px; background-color: red; } .left { height: 400px; width: 20%; background-color: aqua; float: left; } .centre { float: right; height: 400px; width: 80%; background-color: green; } </style> </head> <body> <div class="top"> <a href="">导航一</a> <a href="">导航二</a> <a href="">导航三</a> <a href="">导航四</a> </div> <div class="counter"> <div class="left"> <p><a href="">菜单一</a></p> <p><a href="">菜单二</a></p> <p><a href="">菜单三</a></p> <p><a href="">菜单四</a></p> </div> <div class="centre"> <!-- 此处被替换 --> <form action="" method="post"> <input type="hidden" name="csrfmiddlewaretoken" value="WE..DF"> 用户名:<input type="text"> 密码:<input type="password"> <input type="submit"> </form> </div> </div> </body> </html>
总结:
- 标签extends必须放在首行,base.html 中 block 越多控制性越强
- include 仅仅只是完全引用了其他模板文件 ,而 extends 却可以搭配 block 在引用的基础上进行扩写
- 变量 {{ block.super }} 可以重用父类的内容,然后再父类基础上增加新内容,而不是完全覆盖
- 在一个模板中不能出现重名的block标签。
七、静态文件配置
在网站中我们需要用到大量的css、js 、图片等 ,这些都叫做静态文件。
关于Django中静态文件的配置 ,我们就需要在 settings 配置文件里面写上这样的内容:
1、例如在项目中创建一个 static_file 文件夹来存放静态文件 。
注意:别名可以随便写名字,但是如果改了名字,别忘了如果前端页面如果是通过
/别名/静态文件调用静态文件的话 ,前端页面的静态文件也要更改成一样的
STATIC_URL = '/static/' # 别名 STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static_file') ]
2、前端页面引入静态文件
方式一:不推荐,别名如果有变化,所有应用别名的地方都需要改
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/css/my.css"> </head> <body> <h1 class="c1" id="d1">点我就弹窗</h1> <img src="/static/img/my.png" alt=""> <script src="/static/js/my.js"></script> </body> </html>
方式二:推荐 ,通过 load static 来找到别名,通过别名映射路径的方式来获取静态文件
标签static会接收传入的参数,然后这根据settings.py中变量STATIC_URL的值拼接出一个完整的路径
{% load static %} <!-- 注意:必须先加载文件static.py --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 注意:此处的static是一个定义在 static.py 中的一个标签 ,名字与文件名一样 --> <link rel="stylesheet" href="{% static 'css/my.css' %}"> </head> <body> <h1 class="c1" id="d1">点我就弹窗</h1> <img src="{% static 'img/my.png' %}" alt=""> <script src="{% static 'js/my.js' %}"></script> </body> </html>
方式三:get_static_prefix 标签
和上面的效果一样,不过只是用法不同 。get_static_prefix 不能传参,只能拼接 ,如下:
{% load static %} <!-- 注意:必须先加载文件static.py --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="{% get_static_prefix %}css/my.css"> </head> <body> <h1 class="c1" id="d1">点我就弹窗</h1> <img src="{% get_static_prefix %}img/my.png" alt=""> <script src="{% get_static_prefix %}js/my.js"></script> </body> </html>