模板渲染
语法 {{ 变量 }} {% 逻辑 %}
变量
html代码:
<!-- 万能的点 -->
<p>{{ num }}</p>
<p>{{ name }}</p>
<p>{{ namelist.2 }}</p>
<p>{{ d1.age }}</p>
{#<p>{{ a }}</p> <app01.views.index.<locals>.Animal object at 0x000001F5EA6DD148>#}
<p>{{ a.kind }}</p> <!-- 查看对象属性dog -->
<p>{{ a.eat }}</p> <!-- 执行对象方法,不用带括号,所以不能调用带参数的方法 -->
views.py代码:
def index(request):
num = 100
name = 'shige'
name_list = ['小智','小霞','小刚']
d1 = {'name':'小智','age':13,'hobby':'冒险'}
class Animal:
def __init__(self):
self.kind = 'dog'
def eat(self):
return 'shit'
a = Animal()
return render(request, 'index.html',{'num':num,'name':name,'namelist':name_list,'d1':d1,'a':a})
return render(request, 'index.html',locals()) # 简写,把变量作为键,变量的值作为值全部做成一个字典
# locals()的缺点:拿到全部的变量,但工作开发中不一定要用到全部,可能降低效率
过滤器
<!-- 内置过滤器,在前端进行加工 -->
<!-- 获取数据长度 -->
<p>{{ name_list|length }}</p>
<!-- 默认值,如果一个变量是false或者为空,使用给定的默认值.否则,使用变量的值. -->
<p>{{ xx|default:'nothing!' }}</p>
<!-- filesizeformat 将值格式化为一个“人类可读的”文件尺寸 -->
<p>{{ moviesize|filesizeformat }}</p> <!-- 123123124 -> 117.4 MB -->
<!-- slice 切片 -->
<p>{{ name|slice:':3' }}</p>
<!-- date 日期格式化 Y-m-d H:i:s -->
<p>{{ now|date:'Y-m-d H:i:s' }}</p> <!-- 2020-08-01 -->
<!-- truncatechars 截断字符 汉字算一个字符 -->
<p>{{ words|truncatechars:'9' }}</p> <!-- 'i love you my cat' -> 'i love...' -->
<!-- truncatewords 截断单词 -->
<p>{{ words|truncatewords:'3' }}</p> <!-- 'i love you my cat' -> 'i love you ...' -->
<!-- cut 移除移除变量中所有的与给出的参数相同的字符串 -->
<p>{{ words|cut:' ' }}</p> <!-- 'i love you my cat' -> 'iloveyoumycat' -->
<!-- join 连接字符串 -->
<p>{{ name_list|join:'+' }}</p> <!-- 小智+小霞+小刚 -->
<!-- safe 不必转义 -->
{#<p>{{ value }}</p>#}
<p>{{ value|safe }}</p>
标签
1.模板语言的标签,与html的标签区分开
2.形式{% tag %}。标签的作用:在输出中创建文本,通过循环或逻辑来控制流程,加载其后的变量将使用到的额外信息到模版中。
3.一些标签需要开始和结束标签 (例如{% tag %} ...标签内容 ... {% endtag %})
for 循环标签
循环一个字典
{% for key,value in d1.items %}
<li>{{ key }} --- {{ value }}</li>
{% endfor %}
{% for key,value in d1.items %}
<li>{{ forloop.counter }} {{ key }} --> {{ value }}</li>
{% endfor %}
for循环其他方法
forloop是循环器,通过点来使用功能
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
forloop.parentloop.counter
forloop.parentloop.counter0
......
for empty
for 标签带有一个可选的{% empty %} 从句,以便在给出的循环主体是空的或者没有被找到时,可以有所操作。
{% for animal in animal_list %}
<p>{{ animal.name }}</p>
{% empty %}
<p>sorry,nothing here</p>
{% endfor %}
if
{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
{% if num > 100 or num < 0 %}
<p>无效</p>
{% elif num > 80 and num < 100 %}
<p>优秀</p>
{% else %}
<p>继续努力</p>
{% endif %}
注意的点:
1.不满足条件的,不会生成对应的标签,如num=101,则<p>优秀</p>,<p>继续努力</p>不会生成.
2.不同于python的if-elif-else结构,elif和else都是写在if结构里的.
3.if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格.
4.不支持连续判断,如{% if a > b > c %}...{% endif %}.
with
给复杂的变量起别名
方式一:
{% with total=class23.students.count %}
{{ total }}
{% endwith %}
方式二:
{% with class23.students.count as total %}
{{ total }}
{% endwith %}
注意的点:
1. 命名只能在with语句体内用.
2.等号左右不要加空格!
csrf_token
安全认证机制
<form action="" method="post">
{% csrf_token %}
用户名: <input type="text" name="username">
<button>提交</button>
</form>
# csrf_token相当于服务器给用户返回html页面时盖上了一个戳,等用户再次提交post数据过来的时候,服务器会先检查是否有这个戳,如果有再处理用户数据并作后续处理.就是一种防御机制,来判断用户提交过来的数据是不是按照服务器正常给用户的html页面里输入的.如果非正常则403.
模板继承
urls.py:
# 模板继承
url(r'^home/', views.home),
url(r'^menu1/', views.menu1),
url(r'^menu2/', views.menu2),
url(r'^menu3/', views.menu3),
views.py:
# 模板继承
def home(request):
return render(request, 'home.html')
def menu1(request):
return render(request,'menu1.html')
def menu2(request):
return render(request,'menu2.html')
def menu3(request):
return render(request,'menu3.html')
templates目录:
home.html, menu1.html, menu2.html, menu3.html, base.html(母版,被继承的模板)
母版:写上共有的部分,并在可能要修改的地方留下钩子(可以给子版修改的空间),至少留下div css js三个钩子!
{% block xxx %} | {% block css %} | {% block js %}
... | ... | ...
{% endblock %} | {% endblock %} | {% endblock %}
继承:在需要继承母版的模板中首先写上{% extends 'base.html' %},然后在模板留下的钩子内进行自制化
注意的点:
1.base.html设置越多的 {% block %} 标签越好.
2.子模板不必全用母版的钩子,恰当就好.
3.将子页面的内容和继承的母版中block里面的内容同时保留:在钩子内写上{{ block.super }}.
4.建议给 {% endblock %} 标签写上对应的名字.
5.一个模版中不能定义多个相同名字的block标签.
组件
urls.py:
# 组件
url(r'^nav/', views.nav),
url(r'^newpro/', views.newpro),
views.py:
# 组件(搬运)
def nav(request):
return render(request,'nav.html')
def newpro(request):
return render(request,'newpro.html')
templates目录:
nav.html, newpro.html
newpro.html:
{% include 'nav.html' %} <!-- 引用nav.html的内容 -->