template模板介绍
模板的组成
HTML代码 + 逻辑控制代码
一个完整的渲染过程
Template和Context对象
首先进入该django项目的环境(不一定要在中断测试,也可以在python文件中测试)
python manage.py shell
创建相应的Template对象和Context上下文对象
from django.template import Context, Template t = Template('<h1>hello {{ name }}</h1>') # 实例化一个模板 c = Context({'name': 'Eric'}) # 实例化一个模板对象 t.render(c) # 将上下文对象渲染到模板中
得到的结果是将上下文对象中的变量传入到模板中
>>> 'hello Eric'
上面的过程对比视图函数中的render()方法
render(request, "index.html", {'name': 'Eric'})
- index.html:模板,相当于Template('index.html')
- {'name': 'Eric'}:上下文对象,相当于 Context({'name': 'Eric'})
其实视图函数中也是向上面那样渲染模板的,只不过render()方法将一切已经封装好了,我们在使用时只需要将要渲染的模板跟上下文传进去就可以了
万能的句点符
句点符可以帮助变量深度查找,如果从视图函数传来的是一个对象或者列表,在模板中可没有[],所以只能通过句点号(.) 去查找
在视图函数中:
class Animal: def __init__(name, sex): self.name = name self.sex = sex def index(request): l = ['timo', 'seric', 'scartlett', 'taylor'] a = Animal('Eric', 'male') return render(request, 'index.html', locals())
在index.html中:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <h1>hello</h1> {{ l.1 }} # 通过索引点 {{ l.2 }} {{ a.name }} # 对象直接点属性名字 {{ a.sex }} </body> </html>
变量的过滤器(filter)
语法格式
{{ 要处理的变量|过滤器:传给过滤器的参数 }}
{{ obj|filter:param }}
有哪些过滤器
过滤器 | 说明 |
add | 给变量加上相应的值 |
addslashes | 给变量中的引号前加上斜线 |
capfirst | 首字母大写 |
cut | 从字符串中移除指定的字符 |
date | 格式化日期字符串 |
default | 如果值是False(这里的False是指进行if判断时的False,比如空的列表[],空的字符串''等等,并不是单单值布尔值False),就替换成设置的默认值,否则就是用本来的值 |
default_if_none | 如果值是None,就替换成设置的默认值,否则就使用本来的值 |
safe | 将字符串变成有意义的html代码 |
upper | 将字符串中的所有字符变为大写 |
lower | 将字符串中的所有字符变为小写 |
filesizeformat | 以1024为基数,计算最大值,保留1位小数 |
first | 只取字符串的第一个字母 |
length | 计算字符串的长度 |
slice | 截取字符串指定的前num位 |
urlencode | 对url进行编码 |
过滤器的使用
add
# num = 11 {{ num|add:10 }} # 结果 >>> 21
capfirst
# value = "aBDDGsds" {{ value|capfirst }} >>> ABDDGsds
cut
# value = 'he llo wo r ld' {{ value|cut:' ' }} {# 切掉字符串中所有的空格 #} >>> helloworld
date
# import datetime # value = datetime.datetime.now() {{ value|date:'Y-m-d' }} >>> 2018-07-03
default
# value= [] {{ value|default:'空的' }} >>> 空的
default_if_none
# value = None {{ value|default_if_none:"结果为None" }} >>> 结果为None
safe
# value = "<a href="sssa">click</a>" {{ value }} # 像这样直接渲染是不会被渲染成a标签的,仍旧是原来的字符串<a href="sssa">click</a> {{ value|safe }} # 这样就会在页面呈现一个a标签 >>> click
filesizeformat
# value = 4656461645646 {{ value|filesizeformat }} >>> 4.2 TB
slice
# value = "fdfdsfsdfdsfds" {{ value|slice:"5" }} >>> fdfds
标签(tag)的使用(使用{%%}的组合)
语法格式
{% tags %}}
标签介绍
{% if %}标签
# age = 20 # name = 'aaa' {% if age > 20 %} # 如果age大于20才显示名称 <h1>{{ name }}</h1> {% endif %}
{% elif %}、{% else %}标签
{% if age>20 %} <h1>aaa</h1> {% elif age>30 %} <h1>bbb</h1> {% else %} <h1>ccc</h1> {% endif %}
{% for %}标签
# num = [1, 2, 3, 64, 5, 4, 6] {% for digtal in num %} {{ digtal }} {% endfor %}
forloop计数器
{{ forloop.counter }}
用在的for循环中,计算当前的循环次数,从几开始由counter后面的数字决定
{% for digtal in num %} {{ forloop.counter1 }} # 从1开始计数 {% endfor %}
(( forloop.revcounter ))
倒序,用法跟counter一致,只是计数的顺序从大变到小
{{ forloop.first }}
当循环是第一次时为True,后面的循环都为False
{% empty %}
判断循环中的当前项是否为空
{% for digtal in num %} {{ forloop.counter0 }} {% empty %} # 判断digtal是否为空 <h1>本列为空</h1> {% endfor %}
{% csrf_token %}标签
在使用post方式提交表单时django会有一个中间件验证,这时必须在form标签之中加上{% csrf_token %}进行验证,该标签会在前端渲染一个type为hidden的input标签,名字是固定的,
值相当于一个钥匙,在第一次请求页面的时候就已经发给浏览器了,只有带着这个钥匙去请求才会被通过
例
<form action="" method="post"> <input type="text" name="user"> {% csrf_token %} # 必须加上该验证钥匙 <input type="submit"> </form>
{% with %}标签
用简单的变量名替换复杂的变量名
{% with total=sdsdsdsdsdsdsdsdsdsfdsfsdfsd %} # 用变量名total代替变量名sdsdsdsdsdsdsdsdsdsfdsfsdfsd {{ total }} {% endwith %}
{% url %}
应用别名代替url
urls.py
urlpatterns = [ url(r'index/', views.index, name="index"), ]
index.html
<form action="{% url 'index' %}" method="post"> <input type="text" name="user"> <input type="text" name="pwd"> {% csrf_token %} <input type="submit"> </form>
{% verbatim %}标签
禁止render(),有的时候希望打印{{ hello }},可是由于模板的特性在双大括号之间的内容会被当成变量渲染,这样就达不成想要的效果,这时可以使用{% verbatim %}禁止render()方法去渲染
其它标签
关于{% load %}、{% extends %}、{% include %}会在下面介绍
自定义filter和simple_tag
a、在app中创建templatetags(名字是固定的!!!)模块(即在应用中创建一个python包,必须)
b、在上一步创建的包中添加一个.py文件,比如my_tags.py
my_tags.py
from django import template register = template.Library() # register的名字是固定的,不能够改变 # 定义过滤器 @register.filter def filter_multy(x, y): return x * y # 定义标签 @register.simple_tag def simple_tag_multy(x, y, z): return x * y * z
c、在使用自定义simple_tag或filter的html文件中导入之前创建的my_tags.py
{% load my_tags %}
d、使用simple_tag和filter
index.html
{% load my_tags %} # 首行加载 <!-- 使用过滤器 --> {num|filter_multy:3} # 使用自定义的filter_multy标签,num是从后端传过来的变量 <!-- 使用自定义标签 --> {% somple_tag_multy 1 2 6 %}
e、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
filter与simple_tag的优缺点
filter
- 缺点:只能传一个参数,在需要多个参数的场景中不是很实用,不过可以把多个参数组合成一个列表当做一个参数传进去。
- 优点:filter可以用在if等控制语句当中
simple_tag
- 缺点:simple_tag不能用在if等控制语句当中
- 优点:可以传多个参数,对参数没有限制
as使用:有的时候需要将simple_tag执行的结果保存,这个时候就可以使用as,通过 {% simple_tag_func as variable_name %}
继承标签extends和添加标签include
extends标签
建立一个模板base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <link rel="stylesheet" href="/static/index.css"> </head> <body> <h1>hello</h1> <!-- 在这里放一个盒子,继承该页面的页面可以在这里面定制想要的内容 --> {% block name %} <h1>WELCOME TO LOGIN</h1> {% endblock %} </body> </html>
在别的页面继承base.html
index.html
{% extends "base.html" %} # 一般放在顶行 <!-- 在盒子中定义自己想要的代码,与base.html不同的地方 --> {% block name %} {{ block.super }} # 该变量可以拿到父类盒子中的内容,即<h1>WELCOME TO LOGIN</h1> <h1>index.html</h1> {% endblock %}
include标签
include标签可以将一个html页面引入到另一个html页面中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <link rel="stylesheet" href="/static/index.css"> </head> <body> <h1>hello</h1> <!-- 将index.html页面中的内ring引进来 --> {% include "index.html" %} </body> </html>