目录
Django可以配置一个或多个模板引擎(甚至是О个,如前后端分离,Django只提供API接口,无须使用模板引擎),模板引擎有Django模板语言(Django Template Language,DTL)和Jinja3。
Django模板语言是Django 内置的功能之一,Jinja3是当前Python流行的模板语言。
1.Django5内置模块引擎
Django 内置的模板引擎包含模板上下文(模板变量)、标签和过滤器
功能说明如下:
模板上下文(模板变量):以变量的形式写入模板文件里面,变量值由视图函数或视图类传递所得
标签:对模板上下文进行控制输出,例如模板上下文的循环和判断控制
模板继承隶属于标签,其是将每个模板文件重复的代码抽取出来并写在一个共用的模板文件中,其他模板文件通过继承共用模板文件来实现完整的网页输出
过滤器:对模板上下文进行操作处理,例如模板上下文的内容截取,替换或格式转化
1.1模板上下文
模板上下文是模板中基本的组成单位,上下文的数据由视图函数或视图类传递
以{{ variable }}表示,variable是上下文的名称,它支持 Python 所有的数据类型,如字典、列表、元组、字符串、整型或实例化对象等
需注意:
①当模板引擎遇到一个变量,将计算这个变量,然后输出结果
②变量名必须由字母,数字,下划线,点组成(不能由数字和下划线开头)
③当模板引擎遇到" . "的时候,按以下顺序进行解析
按照dict解析var[key]
按照对象的属性或方法解析var.var/func
按照索引解析var[index]
④如果变量不存在,不会引发异常,模板会插入空字符串
⑤在模板中使用变量或方法时,不能出现(),[],{}
⑥调用方法时,不能传递参数
实例:
views中编写字符串,字典,对象,列表,元组传入到context中:
index.html:
结果:
1.2模板标签
标签是对模板上下文进行控制输出,它是以{% tag %}表示的,其中 tag是标签的名称
常用内置标签如下:
其中for标签,模板提供了一些特殊的变量来获取for标签的循环信息
变量说明如下:
index加入标签:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
字符串: {{ msg01 }}<br>
字典类型: {{ msg02.cat }}<br>
字典类型: {{ msg02.tom }}<br>
对象: {{ msg03.name }},{{ msg03.age }}<br>
列表: {{ msg04.0 }},{{ msg04.2 }},{{ msg04.1 }}<br>
元组: {{ msg05.0 }},{{ msg05.1 }},{{ msg05.2 }},{{ msg05.3 }}<br>
<h3>模板标签</h3>
<p>遍历标签</p>
{% for item in msg04 %}
{{ item }}
<p>这个是第{{ forloop.counter }}次遍历</p>
{% if forloop.first %}
<p>这是第一项 {{ item }}</p>
{% elif forloop.last %}
<p>这是最后一项 {{ item }}</p>
{% endif %}
{% endfor %}
<p>判断标签if</p>
{% if msg01 == '模板变量' %}
<p>模板变量</p>
{% elif msg02 == '模板变量02' %}
<p>模板变量02</p>
{% else %}
<p>其他</p>
{% endif %}
<p>url标签</p>
<a href="{% url 'index' %}" target="_blank">请求index地址</a>
<p>with标签</p>
{% with info=msg01 %}
{{ info }}
{% endwith %}
</body>
</html>
其中<a href="{% url 'index' %}" target="_blank">请求index地址</a>,用来定位路由,是可变的,urls中需要给index/的路由添名称
结果:
1.3模板继承
模板继承是 Django 模板语言中最强大的部分,可以将通用页面元素(例:页眉,页脚,侧边栏等)分离出来,并在多个页面之间共享。大大提高了代码的可重用性,减轻开发人员的工作量。
模板继承使你可以构建基本的“骨架”模板,将通用的功能或者属性写在基础模板中,也叫基类模板或者父模板
子模板可以继承父类模板,子模板继承后将自动拥有父类中的属性和方法,还可以在子模板中对父模板进行重写,即重写父模板中方法或者属性,从而实现子模板的定制
在模板继承中最常用了标签就是 {% block %} 与 {% extends %} 标签,其中 {% block% } 标签与 {% endblock %} 标签成对出现
案例:
建立基类页面:
再写一个页面继承base.html:
在views中添加方法:
urls里添加映射:
结果:
优化代码:
将静态路径修改为读取静态文件:
{% load static %}
,加载项目中的静态文件,包括图片,css,js文件,字体文件等
1.4过滤器
Django过滤器是一种用于在Django模板中处理数据的技术
过滤器的作用是可以对模板中的变量进行加工、过滤或格式化,返回一个新的值供模板使用
过滤器跟模板标签一样,也是在模板中对函数进行调用
过滤器的语法格式如下: {{ 变量 | 过滤器1:参数值1 | 过滤器2:参数值2 ... }}
常用内置过滤器如下:
根据给定的格式格式化日期:
案例:
在views的index方法下新增一个字符串记录时间
index页面中编写
结果:
2.Jinja3模板引擎
Jinja是Python里面被广泛应用的模板引擎
具备以下特性:
沙箱执行模式,模板的每个部分都在引擎的监督之下执行,模板将会被明确地标记在白名单或黑名单内,这样对于那些不信任的模板也可以执行。
强大的自动HTML转义系统,可以有效地阻止跨站脚本攻击。
模板继承机制,此机制可以使得所有模板具有相似一致的布局,也方便开发人员对模板进行修改和管理。
高效的执行效率,Jinja3引擎在模板第一次加载时就把源码转换成Python字节码,加快模板执行时间。
调试系统融合了标准的Python的TrackBack功能,使得模板编译和运行期间的错误能及时被发现和调试。
语法配置,可以重新配置Jinja3,使得它更好地适应LaTeX或JavaScript 的输出。
Django支持 Jinja3模板引擎的使用,由于Jinja3的设计思想来源于Django 的模板引擎,因此Jinja3的使用方法与 Django 的模板语法有相似之处。
开源主页:`https://github.com/pallets/jinja`
官方文档:`https://jinja.palletsprojects.com/en/3.1.x/`
1.1Jinja3安装与配置
可以通过命令安装
pip install Jinja2 -i https://pypi.tuna.tsinghua.edu.cn/simple
也可以直接pycharm解释器中搜索安装
由于 Django的内置功能是使用 Django的模板引擎,如果将整个项目都改为Jinja3模板引擎,就会导致内置功能无法正常使用
在这种情况下,既要保证内置功能能够正常使用,又要使用Jinja3模板引擎,只能将两个模板引擎共存在同一个项目里
首先在项目中新建Jinja3.py定义环境参数:
在settings中修改TEMPLATES信息:
在模板下新建index文件:
结果:
1.2Jinja3模板语法
在功能和使用细节上,Jinja3比Django的模板引擎更为完善,而且Jinja3的模板语法在使用上与 Django的模板引擎存在一定的差异。
复制子项目下template的index.html到父项目下templates中,进行修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
字符串: {{ msg01 }}<br>
字典类型: {{ msg02.cat }}<br>
字典类型: {{ msg02['tom'] }}<br>
字典类型: {{ msg02['tom1'] }}<br>
对象: {{ msg03.name }},{{ msg03.age }}<br>
列表: {{ msg04.0 }},{{ msg04.2 }},{{ msg04.1 }}<br>
元组: {{ msg05.0 }},{{ msg05.1 }},{{ msg05.2 }},{{ msg05.3 }}<br>
<h3>模板标签</h3>
<p>遍历标签</p>
{% for item in msg04 %}
<p>这个是第{{ loop.length }}次循环</p>
{% if loop.first %}
<p>这个是第一项:{{ item }}</p>
{% elif loop.last %}
<p>这个是最后一项:{{ item }}</p>
{% endif %}
{% endfor %}
<p>判断标签if</p>
{% if msg01 == '模板变量' %}
<p>模板变量</p>
{% elif msg02 == '模板变量02' %}
<p>模板变量02</p>
{% else %}
<p>其他</p>
{% endif %}
<p>url标签</p>
{#<a href="{% url 'index' %}" target="_blank">请求index地址</a>#}
<a href="{{ url('index') }}" target="_blank">请求index地址</a>
<p>with标签</p>
{% with info=msg01 %}
{{ info }}
{% endwith %}
</body>
</html>
结果:
在遍历对象,列表,元组的时候,假如元素或者属性不存在,Jinja3会返回具体的报错信息:no such element
以及url函数用法不一样;在遍历for标签上,属性页不一样,内置的对象是loop
for函数模板变量:
把base.html和course.html也复制一份到父项目templates下:
base修改为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block title %}
python
{% endblock %}
</title>
</head>
{#加载静态资源#}
{#{% load static %}#}
<body>
<div id="head">
{# <img src="http://127.0.0.1:8000/static/img.png">#}
<img src="{{ static('img.png') }}">
</div>
<div id="content">
{% block content %}
欢迎
{% endblock %}
</div>
<div id="footer">
版权所有:@#%^&*
</div>
</body>
</html>
结果:
1.3Jinja3过滤器
Jinja3的过滤器与 Django内置过滤器的使用方法有相似之处,也是由管道符号“|”连接模板上下文和过滤器,但是两者的过滤器名称是不同的,而且过滤器的参数设置方式也不同。
Jinja3常用过滤器如下表格:
具体使用可以参考下Jinja3官方文档(`https://jinja.palletsprojects.com/en/3.1.x/templates/#filters` )
修改index.html
结果: