模板和模板引擎
- 模板具有一定的格式或骨架,可以动态的生成HTML
- 模板引擎决定以何种方式组织代码
- 一个项目可以有一个或者是多个模板引擎
- DTL
- Jinja2
DTL
- DTL(Django Template Language)是django)原生的模板系统
- 直到Django1.8,唯一的模板引|擎支持
Jinja.2介绍
- 速度更快,Python的功能齐全的开源模板引擎
- 安装
pip install jinja2
配置选项
settings.png
配置模板选项TEMPLATES
- BACKEND —— 模板引擎配置
- django.template.backends.django.DjangoTemplates
- django.template.backends.jinja2.Jinja2
- DIRS —— 模板引擎按列表顺序搜索这些目录以查找模板源文件
- APP_DIRS —— 决定模板引擎是否应该进入每个已安装的应用中查找模板
- 每种模板引擎后端都定义了一个惯用的名称作为应用内部存放模板的子目录名称
- DTL —— templates目录
- Jinja2 —— jinja2目录
- OPTIONS —— 其他选项配置
同时支持两种模板引擎
- 添加配置模板引擎支持
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates']
},
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [BASE_DIR / 'jinja2']
},
]
同时支持两种模板引擎
- 模板文件查找规则get_template('index..html')
- templates/index.html
- jinja2/index.html
- 模板查找的顺序:
- 按顺序查找、先根目录后模块目录
模板变量的使用
- 语法
- {{ variable }}
- 当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身
- 变量名称中不能有空格或标点符号,不能以”_”开头
渲染Pythonl中的对象
- 语法
- {{ object.attribute }}
- dict类型数据的渲染
- list/tuple类型数据的渲染
- list/tuple嵌套dict复杂类型数据的渲染
DTL与Jinja2的使用区别
- 注意:变量名称中不能有空格或标点符号
- 下面的语法在DTL中不被支持
- {object["a.b"]}
- {object["a b"]}
- 类中的成员方法调用不需要(),也不支持参数传递
# DTL不支持,Jinja2支持
class A():
def display():
return 'hello
# DTL不支持,Jinja2支持
a = A()
{{ a.display }}
模板标签的使用
- 语法
{% tag %}
- 循环控制
- 条件控制
- 模板注释
- URL解析
- with语句块
- 当前时间显示
- 继承与包含
循环控制
{% for item in data_list %}
<li>内容</li>
{% empty %}
<li>暂无内容</li>
{% endfor %}
- 循环内的变量forloop
变量 | 描述 |
---|---|
forloop.first | 如果是第一次迭代,为True |
forloop.last | 如果是最后一次迭代,为True |
forloop.counter0 | 计数器,从0开始 |
forloop.counter | 计数器,从1开始 |
- for循环dict
{% for key,value in data.items %}
{{key}}:{{value}}
{% endfor %}
- 重复循环(循环中再循环)
{% cycle 'row1' 'row2' %}
- 与Jinja2的区别
- 循环变量forloop,Jinja2中为loop
- List为空:
{% empty %}
,Jinja2中为{% else %}
- 循环中的再循环
DTL:{% cycle 'odd' 'even' %}
Jinja2:{{ loop.cycle('odd','even')}}
- DTL不支持continue和oreak
条件控制
{% if condition_a %}
满足了A条件
{% elif condition_b %}
满足了A条件
{% else %}
都不满足
{% endif %}
- ifequal / ifnotequal
{% ifequal a b %}
···
{% endifequal %}
- 循环内ifchanged
模板注释
- 添加注释
{# 注释内容 #}
{% comment "简单的描述" %}
<p>HTML内容{{ create_date }}</p>
{% endcomment %}
URL解析
- URL标签的使用
{% url 'url_name'params %}
<a href="{% url 'index' %}">首页</a>
- statici静态文件URL解析
{% load static %}
<img src="{% static 'images/cat.jpg' %}" alt="Cat">
- 与Jinja2的区别
- DTL
{% url 'url_name' params %}
- Jinja2
{{ url_for('index') }}
- DTL
with语句块
{% with alpha=1 beta=2 %}
···
{% endwith %}
当前时间显示
{% now "jS F Y H:i" %}
模板的继承与包含
模板的抽象和继承
- 步骤一:将可变的部分圈出来(base.html)
{% block sidebar %}
<!-- 菜单栏的内容 -->
{% endblock %}
- 步骤二:继承父模板
只能放第一条语句
{% extends "base.html" %}
- 步骤三:填充新的内容(index.html)
{% extends "base.html" %)
{% block sidebar %}
<!-- 新的菜单栏的内容 -->
{% endblock %}
- 步骤四:复用父模板的内容(可选)
{% extends "base.html" %}
{% block sidebar %}
{{ block.super }}
<!-- 新的菜单栏的内容 -->
{% endblock %}
在模板中添加公共部分
- 步骤一:将可变的部分拆出来(footer.html)
<footer>
这是页脚公共的部分
<footer>
- 步骤二:将拆出来的部分包进来(index.html)
{% extends "base.html" %}
{% block content %}
{{ block.super }}
<!-- 页面主要内容区域 -->
{# 公共的footer #}
{% include "footer.html" %}
{% endblock %}
模板过滤器
什么是过滤器
- 思考:我想对变量进行特殊处理后再渲染?
- 举例:将英语单词转换为大写
- 过滤器语法
- {{ value|filter_name:params }}
- {{ 变量|过滤器名称:参数 }}
- 实例:使用过滤器将字母大写
内置的过滤器
- 默认值显示
- {{ value | default:"" }}
- {{ value | default_if_none:"无" }}
- 数字四舍五入显示
- {{ value | floatformat:3 }}
- 日期对象格式化
- {{ value | date:"D d M Y" }}
- 时间对象格式化
- {{ value | time:"H:i" }}
- 富文本内容转义显示
- {{ value | safe }}
- 字符串截取
- {{ value | truncatechars:9 }}
- {{ value | truncatechars_html:9 }}
- {{ value | truncatewords:2 }}
自定义过滤器
使用场景
- 思考:在什么情况下需要自定义过滤器?
- 手机号、用户名脱敏(隐藏部分**字符串)处理
自定义过滤器
- 步骤一:在
app模块
目录下新建包templatetags
- 步骤二:实现过滤器
poll_extras.py
from django import template
register = template.Library()
def warning(value):
"""将第一个字符变红"""
return '<span class="red">' + value[O] + '</span>+value[1:]'
- 步骤三:注册过滤器
- 方式一:注册过滤器
register.filter('warning',warning)
- 方式二:注册过滤器
@register.filter(name='warning') def warning(value): pass
- 方式一:注册过滤器
- 步骤四:在模板中使用过滤器
{% load poll_extras %}
{{ value | warning }}
注意:
- 添加自定义过滤器后记得重启开发服务器
- 模块需要添加到settings.py中的INSTALLED_APPS内