(五) Django模板templates
模板Templates
一. 概述
模板由两部分组成:
- HTML代码
- 逻辑控制代码
作用: 快速生成HTML页面
优点: - 模板的设计实现了业务逻辑的分离
- 视图可以使用任何的模板
模板的处理: - 从视图中加载数据
- 渲染(将数据变得更漂亮,展示给用户)
二. 定义模板
(1) 变量
- 视图传递给模板的数据
- 要遵循标识符的命名规则
- 语法:
{{变量名称}}
注意: 如果使用的变量不存在, 插入的是空的字符串
(2) 标签
语法: {% tag %}
作用:
- 在输出中创建文本
- 控制逻辑和循环
1. if 标签
语法格式:
{%if 条件 %}
..模板
{%endif}
if其他分支 语法格式:
# 双向分支
{% if 条件 %}
...
{% else %}
...
{% endif %}
# 多向分支
{% if 条件 %}
...
{% elif 条件 %}
..
{% else %}
...
{% endif %}
注意:
- if在模板里也支持嵌套
- ==, !=, >, <, >=, <=, and, or, not, in, not in 都可以在模板中使用
- 运算符左右两侧需要有空格, 语法要求
2. for标签
语法结构:
{% for a in 条件%}
..{{a.属性名}}..
{% endfor%}
在循环中添加reversed, 可以反向迭代(遍历)
{% for s1 in stu reversed %}
<li> {{ s1.sname }}, {{ s1.sage }}</li>
{% endfor %}
配合{% empty %}使用
{% for s1 in sstu reversed %}
<li> {{ s1.sname }}, {{ s1.sage }}</li>
{% empty %}
<h2>为空值</h2>
{% endfor %}
注意: 变量为空或者不存在的时候走empty
{{ forloop. counter }} # 代表当前循环的次数
遍历字典:
# views.py
def myDict(request):
return render(request, 'test.html', {'dict':{'name':'zs', 'age':18}})
# 在templates中
{% for key,val in dict.items %}
{{key}}:{{val}}
{% endfor%}
注意:在模板中直接取出字典的值是 <u>变量名.键名</u>, 而不是<u>变量名['key']</u>
dict.name # ok
dict['name'] # error
变量 | 描述 |
---|---|
forloop.counter | 索引从1开始计算 |
forloop.counter0 | 索引从0开始计算 |
forloop.revcounter | 索引从最大值开始到1 |
forloop.revcounter0 | 索引从最大值开始到0 |
forloop.first | 第一次循环时为真 |
forloop.last | 最后一次循环为真 |
forloop.parentloop | 用在嵌套的for循环中, 获取上一次循环的forloop |
for循环常用的属性
变量 | 描述 |
---|---|
forloop.counter | 索引从1开始计算 |
forloop.counter0 | 索引从0开始计算 |
forloop.revcounter | 索引从最大值开始到1 |
forloop.revcounter0 | 索引从最大值开始到0 |
forloop.first | 第一次循环时为真 |
forloop.last | 最后一次循环为真 |
forloop.parentloop | 用在嵌套的for循环中, 获取上一次循环的forloop |
实例:
{% for l in myList %}
{{ l }}{% if not forloop.last %},{% endif %}
{{ l }} {{ forloop.revcounter0 }}<br>
{% endfor %}
3. ifequal/ifnotequal 标签
{% ifequal %} 比较两个值是否相等
{% ifequal 条件1 条件2 %}
{% endifequal %}
实例:
{% ifequal state state2 %}
<p>{{ state }}和{{ state2 }} 相等</p>
{% else %}
<p>{{ state }}和{{ state2 }} 不相等</p>
{% endifequal %}
# 判断两个条件不相等
{% ifnotequal state dictList %}
<p>{{ state }}和{{ state2 }} 不相等</p>
{% else %}
<p>{{ state }}和{{ state2 }} 相等</p>
{% endifnotequal %}
# 判断是否等于True
{% ifequal True state %}
4. 注释
(1) 单行注释
主体结构: {# 注释的内容 #}
(2) 多行注释
主体结构:
{% comment %}
注释的内容
{% endcomment %}
(3) 跨站请求-csrf
概念: 某些恶意网站, 包含超链接表单, 从而去攻击你的服务器
作用: 用于跨站请求伪造保护
防止csrf在settings.py文件中的配置:
MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware',
]
用法: 在post请求的表单中添加 {% csrf_token %}
(4) include 标签
格式: {% include %} 允许在模板中包含其他的模板的内容
一个网站的模板会将公共的代码提取出来, 方便后期维护和减少代码的冗余
实例:
<body>
{% include 'myApp/header.html' %}
..内容..
<h1>欢迎来到首页</h1>
{% include 'myApp/footer.html' %}
</body>
注意: 如果模板外层没有文件夹的嵌套, 直接写入html文件名即可
{% include 'header.html' %}
{% include 'footer.html' %}
(5) 模板继承和替换
block, extends标签
作用: 用于模板的继承 可以减少页面的内容的重复定义, 实现页面的重用
block标签: 在父模板中预留区域, 在子模板中去替换
主体结构:
{% block 名称 %}
..替换的内容
{% endblock 名称 %}
extends标签
主体结构:
{% extends '父模板的名称和路径' %}
实例:
base.html中
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title%}Title{% endblock %}</title>
</head>
<body>
{% include 'myApp/header.html' %}
{% block main %}
<p>我是base页面的主体部分</p>
{% endblock %}
{% include 'myApp/footer.html' %}
</body>
</html>
继承模板的testtem.html中
{% extends 'myApp/base.html' %}
{% block title %}
模板测试页面
{% endblock %}
{% block main %}
<h1>我是测试页面的主体代码</h1>
{% endblock %}
<h2>我是替换外的代码</h2> # 在模板替换(block)外的代码,不会显示和识别在html中
(6) HTML转义
def func(request):
retrun render(request, 'myApp/index.html', {'html':'<h1>我是html代码</h1>'}) # 会在页面以字符串的形式显示出来,h1不会被转义
1. 使用safe进行转义
{{html|safe}}
2.使用autoescape
{% autoescape off%}
{% html %}
{% endautoescape %}
(7) 过滤器
语法: {{ var | 过滤器}}
作用: 在变量显示之前修改
模板过滤器可以在变量显示之前, 通过管道符对应的变量去修改
实例:
{{a|lower}} # 小写
{{a|upper}} # 大写
1. 第一个/最后一个字母大小写(只会显示出第一个和最后一个字母, 其他会被删除)
{{a|first|lower}} # 第一个字母小写
{{a|last|upper}} # 最后一个字母大写
2. 截取某些个数的值
{{a|truncatewords:3}}
3. 在反斜线和引号前面添加转义\
{{a|addslashes}}
4. join字符串的拼接
{{a|join:'='}}
5. length 返回当前变量的长度
{{ a|length }}
6.default 默认值
{{a:default:'默认值'}}
注意: 当变量不存在或值为False或空的时候, 使用默认值
三. 使用验证码
作用: 确定当前是否为人为操作
在模板中使用:
<p>
验证码: <img src="/yzm/" alt="" onclick="this.src='/yzm/?'+Math.random()">
</p>