模板层相关
模板层
django的模板=HTML代码+模板语法
传值
传递函数名会自动加括号调用,模板语法不支持给函数传额外的参数,传类名的时候也会自动加括号调用(实例化)。
内部能够自动判断出当前的变量名是否可以加括号调用,如果可以就会自动执行,针对的是函数名和类名,本质是触发__call__方法,
对象被展示到html页面上 就类似于执行了打印操作也会触发__str__方法。
传值格式
{{}}:变量相关
{%%}:逻辑相关
深度查询使用句点符取值
"""
一、变量:{{ 变量名 }}
1.1 深度查询:句点符的应用
1.2 过滤器
二、标签:{% 标签名 %}
三、自定义标签和过滤器
四、模板的导入和继承
******************************
******************************
{{}}:变量相关
{%%}:逻辑相关
"""
def index(request):
# 模板语法可以传递的后端数据类型
int_num = 123
float_num = 123.11
str_content = '你好!'
bool_content = True
list_content = [1, 2, 3, 4]
tuple_content = (1, 2, 3)
dict_content = {'username':'张三', 'password':666, 'hobby':[11, 22, 33, {'info':'你好!'}]}
set_content = {"这是集合类型", '集合类型里面的第二个值'}
def func():
print('func函数被执行了')
return '我是func被执行的返回值'
# return render(request, 'index.html', {变量})
return render(request, 'index.html', locals())
<p>{{ int_num }}</p>
<p>{{ float_num }}</p>
<p>{{ str_content }}</p>
<p>{{ bool_content }}</p>
<p>{{ list_content }}</p>
<p>{{ dict_content }}</p>
<p>{{ tuple_content }}</p>
<p>{{ set_content }}</p>
<p>传递函数名会自动加括号调用,模板语法不支持给函数传额外的参数,传类名的时候也会自动加括号调用(实例化){{ func }}</p>
# django模版语法的取值 是固定的格式 只能采用“句点符” .
<p>{{ dict_content.username }}</p>
<p>{{ list_content.0 }}</p>
<p>{{ dict_content.hobby.3.info }}</p>
# 即可以点键也可以点索引 还可以两者混用
过滤器
过滤器类似于python的内置函数,用来把视图传入的变量值加以修饰后再显示,具体语法如下:
{{ 变量名|过滤器名:传给过滤器的参数 }}
常用过滤器
#1、default
# 作用:如果一个变量值是False或者为空,使用default后指定的默认值,否则,使用变量本身的值,
# 如果value=’‘则输出“nothing”
{{ value|default:"nothing" }}
#2、length
# 作用:返回值的长度。
{{ value|length }}
#3、filesizeformat
# 作用:将值的格式化为一个"人类可读的"文件尺寸(如13KB、4.1 MB、102bytes等等),
# 如果 value 是 12312312321,输出将会是 11.5 GB
{{ value|filesizeformat }}
#4、date
# 作用:将日期按照指定的格式输出,
# 如果value=datetime.datetime.now(),按照格式Y-m-d则输出2019-02-02
{{ value|date:"Y-m-d" }}
#5、slice
# 作用:对输出的字符串进行切片操作,顾头不顾尾,
# 如果value=“egon“,则输出"eg"
{{ value|slice:"0:2" }}
#6、truncatechars
# 作用:如果字符串字符多于指定的字符数量,那么会被截断。
# 截断的字符串将以可翻译的省略号序列(“...”)结尾,如果value=”hello world egon 嘎嘎“,则输出"hello...",注意8个字符也包含末尾的3个点
{{ value|truncatechars:8 }}
#7、truncatewords
# 作用:同truncatechars,但truncatewords是按照单词截断,注意末尾的3个点不算作单词,
# 如果value=”hello world egon 嘎嘎“,则输出"hello world ..."
{{ value|truncatewords:2 }}
#8、safe
# 作用:出于安全考虑,Django的模板会对HTML标签、JS等语法标签进行自动转义,
# 例如value="<script>alert(123)</script>",模板变量{{ value }}会被渲染成<script>alert(123)</script>交给浏览器后会被解析成普通字符”<script>alert(123)</script>“,失去了js代码的语法意义,但如果我们就想让模板变量{{ value }}被渲染的结果又语法意义,那么就用到了过滤器safe,比如value='<a href="https://www.baidu.com">点我啊</a>',在被safe过滤器处理后就成为了真正的超链接,不加safe过滤器则会当做普通字符显示’<a href="https://www.baidu.com">点我啊</a>‘
{{ value|safe }}
# *****************************************************
|length
|default
|filesizeformat
|date:'Y-m-d'
|slice:'0:6:2'
|truncatechars(包含三个点)
|truncatewords(不包含三个点 按空格切)
|add
|cut
|join
|safe
标签语法
for循环
{% for value in list_content %} # 类似于for i in [1, 2, 3, 4]
# {# <p>{{ forloop }}</p>#}
<p>{{ value }}</p> # 一个个值
{% endfor %}
"""
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是第一次循环则返回True,否则返回False
forloop.last 当前循环是最后一次循环则返回True,否则返回False
forloop.parentloop 本层循环的外层循环
"""
if判断
# 1、注意:
{% if 条件 %}条件为真时if的子句才会生效,条件也可以是一个变量,if会对变量进行求值,在变量值为空、或者视图没有为其传值的情况下均为False
# 2、具体语法
{% if num > 100 or num < 0 %}
<p>无效</p>
{% elif num > 80 and num < 100 %}
<p>优秀</p>
{% else %}
<p>还凑合吧</p>
{% endif %}
#3、if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
for-if混用
# for与if混合使用
{% for foo in lll %}
{% if forloop.first %}
<p>这是我的第一次</p>
{% elif forloop.last %}
<p>这是最后一次啊</p>
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% empty %}
<p>for循环的可迭代对象内部没有元素 根本没法循环</p>
{% endfor %}
with标签
# with标签用来为一个复杂的变量名起别名,
# 如果变量的值来自于数据库,在起别名后只需要使用别名即可,
# 无需每次都向数据库发送请求来重新获取变量的值
# 在with语法内就可以通过as后面的别名快速的使用到前面非常复杂获取数据的方式
{% with li.1.upper as v %}
{{ v }}
{% endwith %}
csrf_token标签
当用form表单提交POST请求时必须加上标签{% csrf_token%},该标签用于防止跨站伪造请求。
# 当用form表单提交POST请求时必须加上标签{% csrf_token%},该标签用于防止跨站伪造请求
<form action="" method="POST">
{% csrf_token %}
<p>用户名:<input type="text" name="name"></p>
<p>密码:<input type="password" name="pwd"></p>
<p><input type="submit" value="提交"></p>
</form>
# 具体工作原理为:
# 1、在GET请求到form表单时,标签{% csrf_token%}会被渲染成一个隐藏的input标签,该标签包含了由服务端生成的一串随机字符串,如<input type="hidden" name="csrfmiddlewaretoken" value="dmje28mFo...OvnZ5">
# 2、在使用form表单提交POST请求时,会提交上述随机字符串,服务端在接收到该POST请求时会对比该随机字符串,对比成功则处理该POST请求,否则拒绝,以此来确定客户端的身份
自定义过滤器、标签、inclusion_tag
自定义过滤器或标签必须重新启动django方可生效。
三步走战略
"""
1.在应用下创建一个名字”必须“叫templatetags文件夹
2.在该文件夹内创建“任意”名称的py文件 eg:mytag.py
3.在该py文件内"必须"先书写下面两句话(单词一个都不能错)
from django import template
register = template.Library()
"""
自定义过滤器
过滤器最多只能有两个参数。
# 自定义过滤器
@register.filter(name='baby')
def my_sum(v1, v2):
return v1 + v2
# 使用
{% load mytag %}
<p>{{ n|baby:666 }}</p>
自定义标签
@register.simple_tag(name='自定义的标签名'),标签可以接收任意多的参数。
# 自定义标签(参数可以有多个) 类似于自定义函数
@register.simple_tag(name='plus')
def index(a,b,c,d):
return '%s-%s-%s-%s'%(a,b,c,d)
# 使用
标签多个参数彼此之间空格隔开
<p>{% plus 'haha' 123 123 123 %}</p>
自定义inclusion_tag
# 自定义inclusion_tag
"""
内部原理
先定义一个方法
在页面上调用该方法 并且可以传值
该方法会生成一些数据然后传递给一个html页面
之后将渲染好的结果放到调用的位置
"""
@register.inclusion_tag('left_menu.html') # 是个局部的页面 一般不是完整的页面
def left(n):
data = ['第{}项'.format(i) for i in range(n)] # 列表生成式
# 第一种
# return {'data':data} # 将data传递给left_menu.html
# 第二种
return locals() # 将data传递给left_menu.html
{% left 5 %}
# 总结:当html页面某一个地方的页面需要传参数才能够动态的渲染出来,并且在多个页面上都需要使用到该局部 那么就考虑将该局部页面做成inclusion_tag形式
模板的继承、导入
在实际开发中,模板文件彼此之间可能会有大量冗余代码,为此Django提供了专门的语法来解决这个问题,主要围绕三种标签的使用:include标签、extends标签、block标签。
模板的继承
Django模版引擎中最复杂且最强大的部分就是模版继承了。
我们以先创建一个基本的“骨架”模版,它包含我们站点中的全部元素,并且可以定义多处blocks。
# 模版的继承 你自己先选好一个你要想继承的模版页面
{% extends 'home.html' %}
# 继承了之后子页面跟模版页面长的是一模一样的 你需要在模版页面上提前划定可以被修改的区域
{% block content %}
模版内容
{% endblock %}
# 子页面就可以声明想要修改哪块划定了的区域
{% block content %}
子页面内容
{% endblock %}
# 一般情况下模版页面上应该至少有三块可以被修改的区域
1.css区域
2.html区域
3.js区域
{% block css %}
{% endblock %}
{% block content %}
{% endblock %}
{% block js %}
{% endblock %}
# 每一个子页面就都可以有自己独有的css代码 html代码 js代码
"""
一般情况下 模版的页面上划定的区域越多 那么该模版的扩展性就越高
但是如果太多 那还不如自己直接写
"""
模板的导入
"""
将页面的某一个局部当成模块的形式
哪个地方需要就可以直接导入使用即可
"""
{% include '模板的名称' %}
注意事项
#1、标签extends必须放在首行,html文件中block越多可定制性越强
#2、include仅仅只是完全引用其他模板文件,而extends却可以搭配block在引用的基础上进行扩写
#3、变量{{ block.super }} 可以重用父类的内容,然后在父类基础上增加新内容,而不是完全覆盖
#4、为了提升可读性,我们可以给标签{% endblock %} 起一个名字 。例如:
{% block content %}
...
{% endblock content %}
#5、在一个模版中不能出现重名的block标签。

浙公网安备 33010602011771号