目录html
使用 Django的 模板系统 (Template System)来实现将Python代码和HTML代码分开的目的。
python的模板包涵:HTML代码+逻辑控制代码
, 将具体数据嵌入到前端模板的语法,在一个html文件中包含模板语法的文件,能够认为是模板文件前端
主要分为两部分:渲染变量使用双大括号{{ }}
,渲染标签则使用双大括号双百分号{% %}
python
在html页面中使用两个大括号包起来的字符串叫作变量:shell
{{ Var_name }}
这里经过python django的shell环境来举例(在这个环境中能够直接引用 所属django模块中的变量等信息)django
# 使用 manage.py进入shell界面 终端中输入:python manage.py shell >>> from django.template import Context,Template >>> t = Template('My name is {{ name }}') >>> c = Context({'name':'dachenzi'}) >>> t.render(c) # render会把变量进行渲染 'My name is dachenzi' >>>
单行注释 {# #}
。
多行注释 {% comment %} ... {% endcomment %}
.后端
{# 这是一个注释 #} {% comment %} 这是多行注释 {% endcomment %}.
若是传递的变量是属组或者字典,那么须要进行深度查询(经过使用.(点)来完成深度查询):app
{{ Var_Name.username }} # 获取Var_Name中的key为:username的值 --> 变量为字典类型 {{ Var_Name.2 }} # 获取Var_Name中第2个值 --> 变量为list类型
使用.带进行深度查询,查询list类型的数据框架
>>> from django.template import context,Template >>> t = Template('hello {{ name.1}}') >>> c = Context({'name':[1,2,3]}) >>> t.render(c) 'hello 2'
使用items
循环字典类型(不加括号)函数
{% for key,value in user_dict.items %} <li>{{ key }}-{{ value }}</li> {% endfor %}
能够理解为python中的内置函数,过滤器是模板的特有语法,经过前端来过滤部分数据。注意filter只能传递一个参数(也能够说是两个参数,由于第一个个参数已经固定,就是被处理的那个)。
格式:oop
{{ var|method:parameter}}
method表示过滤器部分过滤器以下:
过滤器 | 说明 | 举例 |
---|---|---|
first | 取列表第一个元素 | |
last | 取列表最后元素 | |
capfirst | 首字母大写 | |
cut | 从字符串中移除指定的字符 | {{ 'aLbLcL'|cut:'L' }}答案是abc |
yesno | 变量能够是True、False、None,yesno的参数 给定逗号分隔的三个值,返回3个值中的一个。 True对应第一个 False对应第二个 None对应第三个 若是参数只有2个,None等效False处理 |
{{ value | yesno:"yeah,no,maybe"}} |
add | 加法。参数是负数就是减法 | 数字加{{ value | add:"100"}} 列表合并{{mylist | add:newlist}} |
divisibleby | 可否被整除 {{ value | divisibleby:"3" }}能被3整除返回True | |
addslashes | 在反斜杠、单引号或者双引号前面加上反斜杠 {{ value | addslashes }} | |
length | 返回变量的长度 | {% if my_list | length > 1 %} |
default | 变量等价False则使用缺省值 | {{ value | default:"nothing" }} |
default_if_none | 变量为None使用缺省值 | {{ value |default_if_none:"nothing" }} |
date | 格式化 date 或者 datetime 对象 | 实例:{{my_dict.date|date:'Y n j'}} Y 2000 年 n 1~12 月 j 1~31 日 |
切片相关 | {{ value7|filesizeformat }}文件的字节数 {{ value7|first }}第一个字符 {{ value7|length }}长度 {{ value7|slice:":-1" }}切片 |
内置的过滤器总有不能知足咱们业务需求的时候,这时,咱们能够自定义过滤器,官方文档:https://docs.djangoproject.com/zh-hans/2.0/howto/custom-template-tags/
具体步骤为:
app目录下
建立templatetags包(名称必须为templatetags
)下面是my_tags.py的文件内容
from django import template # 须要先导入文件 register = template.Library() # register的名字是固定的,不可改变,由于下面会进行调用 @register.filter # 注册 def multi(num1,num2): return num1 * num2
在引用的html模板文件中进行加载(能够放在模板文件头部,或者用以前加载也能够,当和extend同时使用时,放在entend下面)
{% load my_tags %} # 这里的名字就是咱们建立的my_tags.py的文件名
调用
{{ hello|multi:2 }} # hello 表示传递的第一个参数,2表示传递的是第二个参数,冒号后面必需要紧跟传递的参数,多一个空格都不行
PS:filter 的函数只能接受一个额外参数(两个参数,默认会把要处理的对象看成第一个参数,第二个参数是咱们须要传递的参数),能够用于if/for等语句的条件,渲染时 使用 {{ 参数1 | xxx:参数2 }} 渲染 。
simpletag与filter不一样的是,能够接受多个参数,但不能够用if/for等语句的条件,使用 {% xxx %} 渲染,建立步骤与filter相同
编写simpletag
# my_tags.py文件 from django import template # 须要先导入文件 register = template.Library() # register的名字是固定的,不可改变,由于下面会进行调用 @register.simple_tag # 必需要装饰咱们自定义的函数才行 def simple_tag_multi(num1,num2): return num1 * num2
加载完毕后调用方式使用 {% %}
{% simple_tag_multi 10 20 %} # 参数以空格隔开,多个空格效果相同
循环等逻辑语句须要使用{% %} 来进行渲染
{% for i in li %} # li 为后端传递给模板的变量 <p>{{ i }}</p> {% endfor %} #使用endfor来表示循环结束
在for循环中存在一个forloop变量,该变量记录循环相关数据
reversed和empty:
reversed
:对可迭代对象进行逆序empty
:若是可迭代对象为空{% for athlete in athlete_list reversed %} ... {% empty %} ... 若是被迭代的列表是空的或者不存在,执行empty {% endfor %}
{% if li.1 > 100 %} <p> 大于 </p> {% elif li.1 < 100 %} <p> 小于 </p> {% else %} <p> 等于 </p> {% endif %} #使用endif来表示条件判断结束
{% ifequal %} 标签比较两个值,当他们相等时,显示在 {% ifequal %} 和 {% endifequal %} 之中全部的值。
下面的例子比较两个模板变量 user 和 currentuser :
{% ifequal user currentuser %} <h1>Welcome!</h1> {% endifequal %}
和 {% if %} 相似, {% ifequal %} 支持可选的 {% else%} 标签
{% ifequal section 'sitenews' %} <h1>Site News</h1> {% else %} <h1>No News Here</h1> {% endifequal %}
{% url 'varname' %}
:引用路由配置的地址
<form action="{% url "LOGIN"%}" method="POST"> # 路由引用 <input type="text"> <input type="submit" value="提交"> </form>
{% verbatim %}
:禁止render解析。
既在有的时候咱们仅仅只是想打印出 {{ hello }} 而已,使用verbatim来禁止render进行解析
{% verbatim %} {{ hello }} {% endverbatim %} # 使用verbatim 包起来的代码 将不会进行解析
{% csrf_token %}
:用于跨站请求伪造保护,防止跨站攻击的。
<form> {% csrf_token %} </form>
通常用在form表单中。
到目前为止,咱们的模板范例都只是些零星的 HTML 片断,但在实际应用中,你将用 Django 模板系统来建立整个 HTML 页面。 这就带来一个常见的 Web 开发问题: 在整个网站中,如何减小共用页面区域(好比站点导航)所引发的重复和冗余代码?Django 解决此类问题的首选方法是使用一种优雅的策略 —— 模板继承
.
本质上来讲,模板继承就是先构造一个基础框架模板,然后在其子模板中对它所包含站点公用部分和定义块进行重载.
编写模板须要使用模板标签:
{% block name%} {% endblock %}
:全部的 {% block %} 标签告诉模板引擎,子模板能够重载这些部分。 每一个{% block %}标签所要作的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。
下面是一个html模板文件:
// index.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div class="title"></div> <div class="left"> <div class="left_list"> <a href="/booklist/">文章列表</a> </div> </div> <div class="right"> {% block content %} // 这里定义content,表示这里能够被继承模板进行替换 {% endblock %} // 包起来的表示代码段 </div> </body> </html>
HTML中包含 block 语句块的均可以称为模板文件
子模板进行继承,并定制本身要显示的内容(子模板不须要额外的html代码,其代码都来自于模板文件),仅仅须要定义 block块内的信息便可,固然也能够不定义,或者在block块中调用父模板的内容。
// test.html {% extends 'index.html' %} // 继承模板文件 {% block content %} // 针对模板中content的代码块进行定义 <h1>hello world</h1> <h1>hello world</h1> <h1>hello world</h1> <h1>hello world</h1> <h1>hello world</h1> <h1>hello world</h1> {% endblock %}
使用注意:
第一个
模板标记(html首部
)。 不然,模板继承将不起做用。{{ block.super }}
这个标签吧,这一个魔法变量将会表现出父模板中的内容。 若是只想在上级代码块基础上添加内容,而不是所有重载,该变量就显得很是有用了。一个html文件只能引入一个模版
在不少网站中,基本上的都会有一个开头和一个结尾,在每个网页中都会显示。相对于这种的来讲,在Django中,最好的方法就是使用include的标签,在每个模板中都加入这个开头和结尾的标签。
简单来讲,就是那些多个页面都须要的公共标签放在一个统一的html文件,供其余html文件引入。
{% include 'tpl.html' %} : 表示引入tpl.html文件。
看下面的例子:
# -------------------- tpl.html -------------------- <div> <h1>hello world</h1> </div> # -------------------- xxx.html -------------------- ... <div> {% include 'tpl.html' %} {% include 'tpl.html' %} // tpl.html的所有内容会在这里填充 ... </div> ...
在一个页面中能够经过include引入不一样的公共组件。