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>

浙公网安备 33010602011771号