共计 4963 个字符,预计需要花费 13 分钟才能阅读完成。
一、标签说明
语法: {% tag %}
作用
- 在输出中创建文本
- 控制逻辑和循环
二、if 标签
-
说明
==, !=, >=, <=, >, < and, or, not, in, not in 这些操作符都可以在模板中使用
-
格式
格式一:单一条件分支
{% if condition %} ... display {% endif %}
格式二:双向条件分支
{% if condition %} ... display {% else %} ... display {% endif %}
格式三:多向条件分支
{% if condition1 %} ... display 1 {% elif condition2 %} ... display 2 {% else %} ... display 3 {% endif %}
-
实例
{% if 'l' in 'lucky' %} <h2>l 在 lucky 字符串中</h2> {% else %} <h2>l 不在 lucky 字符串中</h2> {% endif %} {% if athlete_list and coach_list %} athletes 和 coaches 变量都是可用的。{% endif %}
-
注意
表达式中不能使用算术运算符
if/else 支持嵌套
三、for 标签
-
说明
与 Python 的 for 语句的情形类似,循环语法是 for X in Y,Y 是要迭代的序列而 X 是在每一个特定的循环中使用的变量名称
每一次循环中,模板系统会渲染在 {% for %} 和 {% endfor %} 之间的所有内容
-
格式
格式一
{% for var in sequence %} ... {% endfor %}
格式二 搭配 empty
{% for var in sequence %} ... {% empty %} ... {% endfor %}
-
注意
迭代对象不存在或对象为空值时执行 empty 语句
-
使用
遍历字典
def home(request): info_dict = {'name': 'lucky', 'age': 18} return render(request, 'home.html', {'info_dict': info_dict})
模板
{% for key, value in info_dict.items %} {{key}}: {{value}} {% endfor %}
-
reversed 反向迭代
{% for name in name_list reversed %}
...
{% endfor %}
-
嵌套使用 {% for %} 标签
{% for i in info %} <h1>{{i}}</h1> <ul> {% for sport in athlete.sports_played %} <li>{{sport}}</li> {% endfor %} </ul> {% endfor %}
-
获取迭代状态
变量 描述 forloop.counter 索引从 1 开始算 forloop.counter0 索引从 0 开始算 forloop.revcounter 索引从最大长度到 1 forloop.revcounter0 索引从最大长度到 0 forloop.first 当遍历的元素为第一项时为真 forloop.last 当遍历的元素为最后一项时为真 forloop.parentloop 用在嵌套的 for 循环中,获取上一层 for 循环的 forloo
四、ifequal/ifnotequal 标签
-
作用
判断是否相等 / 不相等
-
格式
-
ifequal
{% ifequal 表达式 1 表达式 2 %} 语句 {% endifequal %}
搭配 else
{% ifequal 表达式 1 表达式 2 %} 语句 1 {% else %} 语句 2 {% endifequal %}
-
ifnotequal
{% ifnotequal 表达式 1 表达式 2 %} 语句 {% endifnotequal %}
搭配 else
{% ifnotequal 表达式 1 表达式 2 %} 语句 1 {% else %} 语句 2 {% endifnotequal %}
-
五、注释标签
-
作用
代码调试
解释说明
-
格式
单行注释
{# 语句 #}
多行注释
{% comment %} 语句 {% endcomment %}
-
使用
单行注释
{# <h1>lucky is a cool man</h1> #}
多行注释
{% comment %} <h1>lucky is a cool man</h1> <h1>lucky is a handsome man</h1> {{stu.sname}} {% endcomment %}
-
注意
注释的代码都不会再浏览器的 HTML 页面中显示出来
六、include 导入
-
说明
include
语句可以把一个模板引入到另外一个模板中,类似于把一个模板的代码 copy 到另外一个模板的指定位置 -
使用
目录结构
project/ App/ templates/ common/ header.html footer.html
header.html
<nav>我是头部</nav>
footer.html
<footer>底部</footer>
test_include.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> *{padding:0; margin: 0; } nav{width:100%; height: 40px; background-color: #000; color: #fff; } footer{width:100%; height: 100px; background-color: orange; position: absolute; bottom:0; } </style> </head> <body> {% include 'common/head.html' %} <div>我是中间主体部分</div> {% include 'common/footer.html' %} </body> </html>
-
注意
导入的文件的代码一定是当前需要的 不要添加任何其它的代码 包括主体结构 否则会将当前页面的所有代码包含进来
七、模板继承
-
概述
Django
中的模板可以继承,通过继承可以把模板中许多重复出现的元素抽取出来,放在父模板中,并且父模板通过定义block
给子模板开一个口,子模板根据需要,再实现这个block
-
作用
用于模板的继承 可以减少页面的内容的重复定义,实现页面的重用
-
block 标签
在父模板中预留区域,子模板去填充
格式
{% block 标签名 %} ... {% endblock 标签名 %}
-
extends 标签
用于子模板继承父模板 并实现模板复用
格式
{% extends '父模板路径' %}
注意:该标签必须写在子模板中的第一行
-
使用
基础模板 base.html
<!DOCTYPE html> <html lang="en"> <head> {% block head %} {# 开放一个地方,以待具体赋值 #} <style> #content{font-size:20px;} </style> <title>{% block title %}title{% endblock %}</title> {% endblock %} </head> <body> <div id="content"> {% block content %} <div> 这里是默认内容,所有继承自这个模板的,如果不覆盖就显示这里的默认内容。</div> {% endblock %} </div> {% block footer %} © Copyright 2008 by <a href="#">lucky</a>. {% endblock %} </div> </body> </html>
子模板 children.html
{% extends "base.html" %} {# 1: 继承父模板 #} {% block title %}Index{% endblock %} {# 2: 书写 title block #} {% block head %} {#3:书写 head block #} {{block.super}} {# 4 调用父模板中的内容,如果不调用,则此处会被子模板中书写的内容覆盖掉 #} <style type="text/css"> .important {color: #336699; } </style> {% endblock %} {% block content %}{# 5: 书写 content block #} <h1>Index</h1> <p class="important"> Welcome to my lucky homepage. </p> {% endblock %}
-
注意
- 当重写了一个 block,原来的显示内容就没了,八成的原因是没有调用 super
- 在模板中不能有同名的 block
- 不支持多继承
八、对比包含、继承
-
相同点
均实现了代码的复用
-
不同点
-
包含是直接将目标文件整个渲染出来
-
继承的本质是代码的替换,一般用来实现页面中重复不变的区域
-
九、url 地址
-
命名空间
path(r'', include(('App.urls', 'App'), namespace='App')),
-
无参路由
path(r'index/', views.index, name='index')
<a href="{% url'App:index'%}">首页</a>
-
构造带参路由地址
path(r'args/<str:name>/<int:age>/', views.args, name='args'),
re_path(r'args/(\w+)/(\d+)/', views.args, name='args'),
{# 普通参数 #} <a href="{% url'App:args''lucky' 18 %}">args</a> #/args/lucky/18/
-
关键字参数构造路由地址
path(r'args/<str:name>/<int:age>/', views.args, name='args'),
re_path(r'args/(?P<name>\w{3,5)/(?P<age>\d{1,2})/', views.args, name='args'),
{# 关键字参数 #} <a href="{% url'App:args'name='lucky'age=18 %}"> #/args/lucky/18/
十、跨站请求伪造 csrf
-
说明
某些恶意的网站上包含链接、表单按钮或者 JavaScript 代码,他们会利用登陆过的信息试图在你的网站上完成某些操作,这就是跨站攻击
-
作用
在客户端生成一个名为 csrftoken 的 cookie
在页面生成一个隐藏域,name 值为 csrfmiddlewaretoken,value 值会根据 cookie 的值进行计算生成
用于跨站请求伪造保护
-
原理
请求会带着 cookie 到服务端,服务器中的中间件 (六娃) 首先会获取键名为 csrftoken 的 cookie 的值,在获取表单中键为 csrfmiddlewaretoken 的值,在进行对比运算,如果符合条件则继续请求,否则中断请求,并返回给客户端 403 错误
-
防止 CSRF
在 settings.py 文件中的 MIDDLEWARE 增加 **(默认已开启)**
'django.middleware.csrf.CsrfViewMiddleware',
-
格式
{% csrf_token %}
-
使用
<form action="{% url'App:dologin'%}" method="post"> {% csrf_token %} ... </form>
十一、autoescape 标签
-
作用
HTML 转义标签
-
注意
Django 服务默认开启转义
-
使用
return render(request,'App/index.html',{"code":"<h1>lucky is a very good man</h1>"}) {{code}}
safe
{{code|safe }}
autoescape off 渲染
{% autoescape off %} {{code}} {% endautoescape %}
autoescape on 不渲染
{% autoescape on %} {{code}} {% endautoescape %}
十二、数学运算
-
加法
{{value|add:10 }}
说明:value=5, 则结果返回 15
-
减法
{{value|add:-10 }}
说明:value=5, 则结果返回 -5,加一个负数就是减法了
-
乘法
{% widthratio 5 1 100%}
说明:等同于:(5 / 1) * 100,结果返回 500,withratio 需要三个参数,它会使用参数 1 / 参数 2 * 参数 3 的方式进行运算,进行乘法运算,使参数 2 =1
-
除法
{% widthratio 5 100 1%}
说明:等同于:(5 / 100) * 1, 则结果返回 0.05, 和乘法一样,使 参数 3 = 1 就是除法了