目录
模板是什么
模板变量
模板标签
过滤器
模板继承
csrf_token标签
作为一个网络框架,Django 需要一种方便的方式来动态生成 HTML。最常见的方法是依靠模板。一个模板包含了所需 HTML 输出的静态部分,以及一些特殊的语法,描述了如何插入动态内容。简单说可以理解为占位符,将动态信息提前在HTML文件中固定号位置,然后让Django进行渲染生成HTML文件即可。
注意:模板的语法只有在Django中有用,在其他地方中使用模板的语法编写是没有效果的。
Django模板语言的语法包括了四个部分:变量、标签、过滤器和注释。为了更好地书写或者阅读模板
语法格式:
{{ 变量名 }}
Django对变量的命名限制较少,它可以是任何字母、数字和下画线的组合,但是变量名称中不可以有空格或标点符号。
变量名中的点是比较特殊的,Django按照如下的顺序在上下文中查找变量。
模板系统按照顺序依次查找,直到找到第一个可用的值完成变量替换。
Django模板系统对标签的解释是在渲染的过程中提供任意的逻辑,它看起来像{%tag%}这样。标签常常用于在输出时创建文本、控制循环和判断逻辑以及装载外部信息
判断执行逻辑的if标签
{% if 表达式1 %}
代码1
{% elif 表达式2 %}
代码2
......
{% else %}
代码3
{% endif %}
可以使用and和or连接多个条件,也可以使用not对当前的条件取反。同时,也可以在条件中使用>、==、<=等算术操作符。
迭代序列元素的for标签
{% for 变量名 in 可迭代对象 %}
代码1
{% empty %}
代码2
{% endfor %}
语法 Python中的for语法是类似的,并且支持一个可选的empty子句,用于定义当可迭代对象不存在或没有元素时显示的内容。
与Python中的for循环不同的是,for标签只能一次性地遍历完列表中的元素,不能中断(break),也不能跳过(continue)。这就要求传递到上下文中的变量包含确定需要的值,即用业务逻辑控制列表中的元素。
可以使用{% for obj in list reversed %}来反向循环一个列表。
并且在for 循环还设置了一组可以在循环体内直接使用的变量:
过滤器用于在显示变量之前对变量的值进行调整,它们在模板中很常见,使用管道符号(|)指定。有些过滤器可以接受参数,如果参数中带有空格,则需要用引号括起来。过滤器的特色是可以通过组合多个过滤器实现链式调用。过滤器相比标签要简单许多,可以认为过滤器就是一个Python函数,传递参数给它,处理完之后返回到模板中。
{{ 变量名|length }}
{{ 变量名|upper }}
{{ 变量名|lower }}
{{ 变量名|first }}
{{ 变量名|last }}
{{ 变量名|truncatechars:个数 }}
truncatewords过滤器接受一个参数,指定需要保留的单词个数,多出来的词用省略号替换。参数需要与过滤器用冒号分开,
{{ 变量名|date:"Y-m-d" }}
{{ 变量名|safe }}
但变量名所表示的是文本内容时,如HTML文本,直接放在模板中会被django标记为不安全所直接输出文本内容,不会使用HTML描述网页,这个时候则需要使用这个过滤器,表示这个文本是安全的,就可以显示HTML所描述的网页了
{{ 变量名|add:int }}
int表示一个整型数据,可以为负数,为负数时表示解法
以上只是常用的时间格式。
一些高级语言有继承的功能,将通用的功能或属性写在父类(或基类)里面,子类继承自父类,即自动拥有父类的所有属性和方法。同时,还可以通过重写父类中的属性和方法实现定制。这样的继承特性,通过抽象共性,减少了大量的重复代码。Django模板系统同样支持继承,这是一个非常有用的功能,在实际的项目开发中模板继承也是非常常见的。
模板继承使用起来非常简单,只需要定义好被继承的父模板,其中包含通用元素和可以被子模板覆盖的block部分即可。
{% block title %}My amazing site{% endblock %}
{% block content %}{% endblock %}
上面这个模板,我们称之为 base.html
,它定义了一个 HTML 骨架文档,你可以用它来制作一个两栏式页面。“子”模板的工作是用内容填充空块。
在这个例子中,block 标签定义了三个块,子模板可以填入其中。block 标签所做的就是告诉模板引擎,子模板可以覆盖模板的这些部分。
下面的子模板可能是这样的
{% extends "base.html" %}
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
{{ entry.title }}
{{ entry.body }}
{% endfor %}
{% endblock %}
extends 标签是这里的关键。它告诉模板引擎,这个模板“扩展”了另一个模板。当模板系统执行这个模板时,首先要找到父模板——在本例中是“base.html”。
这时,模板引擎会注意到 base.html
中的三个 block 标签,然后用子模板的内容替换这些块。根据 blog_entries
的值,输出可能是下面这样的:
My amazing blog
Entry one
This is my first entry.
Entry two
This is my second entry.
注意:
模板继承是模板系统中最强大也是最复杂的功能,它的用途非常广泛。通常,如果是在多个模板中出现了大量的重复代码,那么,就应该考虑使用模板继承来减少重复性代码。另外,Django建议,父模板中的{%block%}标签应该越多越好,毕竟,子模板不需要完全重写所有的标签,所以,可以多定义一些通用或者默认的内容。
这个标签用于 CSRF 保护,CSRF 中间件和模板标签提供了易于使用的保护,防止跨站请求伪造。 当一个恶意网站包含一个链接、一个表单按钮或一些 JavaScript,目的是在你的网站上执行一些操作,使用在浏览器中访问恶意网站的登录用户的凭证时,就会发生这种类型的攻击。 此外,还包括一种相关的攻击类型,“登录 CSRF”,即攻击网站欺骗用户的浏览器使用他人的凭证登录网站。
如果在任何使用 POST 表单的模板中,如果表单是针对内部 URL 的,请在 元素中使用
csrf_token
标签,如:
对于以外部 URL 为目标的 POST 表单,不应该这样做,因为这会导致 CSRF 令牌泄露,从而导致漏洞。