52.2 模板层(templates)
1.模板语法符号
模板语法符号 {{}} 变量相关 {%%} 逻辑相关
2.模板传值
模板层之模板传值 支持数据类型 python基本数据类型全部支持传递给html文件 函数 类 函数和类会自动加括号 # 模板语法类 函数不支持传参 对象 obj可以直接传过去 通过obj.name方式取值 两种传参方式 后端给html文件传递数据的两种方式 1.指名道姓 return render(request,'index.html',{'n':n,'f':f}) 2.locals() # 会将当前名称空间中所有的变量名全部传递给html页面 return render(request,'index.html',locals()) ps:. html页面上 如何获取到后端传递过来的数据 {{ 变量名 }}
3.模板取值
django模板语法取值 只有一种操作方式 句点符 .
点索引 列表
点键 字典
点属性 对象
<p>{{ l.2 }}</p>
<p>{{ d.username }}</p>
<p>{{ d.password }}</p>
<p>{{ d.hobby.1.username.1 }}</p> #字典嵌套列表
4.模板语法之过滤器
|length |add |default |truncatechars |truncatewords |filesizeformat |slice |date |safe <p>过滤器 |左边的会当做过滤器的第一个参数 过滤器名右边的会当做过滤器的第二个参数</p> <p>求数据长度:{{ s|length }}</p> <p>加法运算:{{ n|add:10 }}、{{ s|add:13132 }}、{{ s|add:'DSB' }}</p> <p>默认值(判断值是否为空):{{ b|default:'这个b布尔值是True' }}、{{ ff|default:'这个ff布尔值是Flase' }}</p> <p>截取字符(截取5个字符 三个点也算):{{ s|truncatechars:8 }}</p> <p>截取单词(截取8个单词 三个点不算):{{ ss|truncatewords:8 }}、{{ sss|truncatewords:4 }}</p> <p>文件大小:{{ file_size|filesizeformat }}</p> <p>切片操作:{{ s|slice:'0:2' }}、{{ s|slice:"0:8:2" }}</p> <p>日期格式化:{{ ddd|date:'Y年/m月/d日' }}</p> <p>转义:{{ res|safe }}、{{ res1 }}、后端直接标识安全:{{ res2 }}</p> 前后端取消转义 前端 |safe 后端 from django.utils.safestring import mark_safe mark_safe('<h1>安全滴</h1>') 总结:前端代码不一定非要在前端页面写,可以在后端写好传递给前端页面使用 这样的话 你就可以利用到后端更加多的逻辑语法
5.模板语法--标签(逻辑相关)
{% for foo in l %} <!--l = [1,2,3,4,5,6]--> {% if forloop.first %} <p>这是我的第一次</p> {% elif forloop.last %} <p>这是最后一次了啊~</p> {% else %} <p>{{ foo }}</p> {% endif %} {% empty %} <p>for循环的对象内部没有值</p> {% endfor %} {#<p>当一个值获取的步骤非常繁琐 但是又需要在很多地方用到 我们可以用起别名的 方式来简化代码</p>#} {#{% with d.hobby.1.username.1 as eg %}#} {# <p>别名只能在with内使用:{{ eg }}</p>#} {# <p>{{ d.hobby.1.username.1 }}</p>#} {#{% endwith %}#}
循环自带的forloop 解释
{#{% for foo in l %}#} {# <p>{{ forloop }}</p>#} {#{% endfor %}#} {#{% for foo in bbb %} <!--l = [1,2,3,4,5,6]-->#} {# {% if forloop.first %}#} {# <p>这是我的第一次</p>#} {# {% elif forloop.last %}#} {# <p>这是最后一次了啊~</p>#} {# {% else %}#} {# <p>{{ foo }}</p>#} {# {% endif %}#} {# {% empty %}#} {# <p>for循环的对象内部没有值</p>#} {#{% endfor %}#}
6.自定义 过滤器 和 标签
自定义过滤器 标签 inclusion_tag 先完成以下前期准备工作 1.在应用名下新建一个名字必须叫templatetags文件夹 2.在该文件夹内新建一个任意名称的py文件(eg:mytag) 3.在该文件内 必须先写以下两句代码 from django.template import Library register = Library() # 自定义过滤器 @register.filter(name='my_sum') def index(a,b): return a + b # 自定义标签 @register.simple_tag(name='my_baby') def xxx(a,b,c,d): return '%s?%s?%s?%s'%(a,b,c,d) # 自定义inclusion_tag @register.inclusion_tag('demo.html',name='myin') def index1(n): l = [] for i in range(n): l.append(i) # 将列表传递给demo.html # return locals() return {'l':l} <p>自定义过滤器的使用</p> {% load mytag %} <p>{{ 10|my_sum:90 }}</p> <p>自定义标签的使用</p> {% load mytag %} <p>{% my_baby 1 2 3 'hello world' %}</p> <p>自定义的过滤器可以在逻辑语句中而自定义的标签不可以</p> {% if 10|my_sum:100 %} <p>条件成立</p> {% endif %} {% if my_baby 1 2 3 4 %} <p>条件成立</p> {% endif %} <p>自定义inclusion_tag的使用</p> {% load mytag %} {% myin 5 %} # 总结 页面上使用他们 统一先导入 {% load mytag %}
自定义过滤器
自定义标签
自定义标签include_tag
原理图 非此图中的函数
自定义标签html页面 不需要完整的页面结构
示例解释:
views
import time from datetime import datetime from django.utils.safestring import mark_safe def index(request): # python所有的数据类型都支持传递给html页面 n = 11 f = 11.11 s = 'hello world' l = [1,2,3,4,5,6] d = {"username":'jason','password':123,'hobby':['read',{'username':['jason','egon']}]} t = (1,2,3,4,5,6,7,) se = {1,2,3,4,5,6} b = True ff = False ss = 'kjasdklas ksd;lk akjsdkl da kjda k;lak d k;a dk ska d' sss = '卡时间 冻结 鲨科 技的 卡拉 手动 卡萨 丁卡' file_size = 32213213424 def func(xxx,yyy): print('func被执行了') return 'from func' class MyClass(object): def get_self(self): return 'from self' @staticmethod def get_func(): return 'from func' @classmethod def get_cls(cls): return 'from cls' obj = MyClass() # 1 给模板传递数据 # return render(request,'index.html',{'n':n,'f':f}) # 2 给模板传递数据 ttt = time.time() ddd = datetime.now() res = "<h1>你好啊</h1>" bbb = [] res1 = "<script>alert(123)</script>" res2 = mark_safe("<h1>你好啊</h1>") return render(request,'index.html',locals()) # 会将当前名称空间中所有的变量名全部传递给html页面 # 为了教学演示方便 我们后面就用第二种
templates
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> {#<p>{{ n }}</p>#} {#模板语法的注释 这个注释前端浏览器检查是看不见的#} <!--浏览器检查能够看到--> {#<p>{{ f }}</p>#} {#<p>{{ s }}</p>#} {#<p>{{ l }}</p>#} {#<p>{{ d }}</p>#} {#<p>{{ t }}</p>#} {#<p>{{ se }}</p>#} {#<p>{{ b }}</p>#} {#<p>函数名会自动加括号执行 展示的是函数的返回值:{{ func }} 模板语法不支持给函数传参</p>#} {#<p>传类名 也会自动加括号实例化{{ MyClass }}</p>#} {#<p>{{ MyClass }}</p>#} {#<p>{{ MyClass.get_func }}</p>#} {#<p>{{ MyClass.get_cls }}</p>#} {#<p>{{ MyClass.get_self }}</p>#} {#<p>{{ obj }}</p>#} {#<p>{{ obj.get_func }}</p>#} {#<p>{{ obj.get_self }}</p>#} {#<p>{{ obj.get_cls }}</p>#} {#<p>取值</p>#} {#<p>{{ l.2 }}</p>#} {#<p>{{ d.username }}</p>#} {#<p>{{ d.password }}</p>#} {#<p>{{ d.hobby.1.username.1 }}</p>#} {#<p>过滤器 |左边的会当做过滤器的第一个参数 过滤器名右边的会当做过滤器的第二个参数</p>#} {#<p>求数据长度:{{ s|length }}</p>#} {#<p>加法运算:{{ n|add:10 }}、{{ s|add:13132 }}、{{ s|add:'DSB' }}</p>#} {#<p>默认值(判断值是否为空):{{ b|default:'这个b布尔值是True' }}、{{ ff|default:'这个ff布尔值是Flase' }}</p>#} {#<p>截取字符(截取5个字符 三个点也算):{{ s|truncatechars:8 }}</p>#} {#<p>截取单词(截取8个单词 三个点不算):{{ ss|truncatewords:8 }}、{{ sss|truncatewords:4 }}</p>#} {#<p>文件大小:{{ file_size|filesizeformat }}</p>#} {#<p>切片操作:{{ s|slice:'0:2' }}、{{ s|slice:"0:8:2" }}</p>#} {#<p>日期格式化:{{ ddd|date:'Y年/m月/d日' }}</p>#} {#<p>转义:{{ res|safe }}、{{ res1 }}、后端直接标识安全:{{ res2 }}</p>#} {#<p>标签</p>#} {#{% for foo in l %}#} {# <p>{{ forloop }}</p>#} {#{% endfor %}#} {#{% for foo in bbb %} <!--l = [1,2,3,4,5,6]-->#} {# {% if forloop.first %}#} {# <p>这是我的第一次</p>#} {# {% elif forloop.last %}#} {# <p>这是最后一次了啊~</p>#} {# {% else %}#} {# <p>{{ foo }}</p>#} {# {% endif %}#} {# {% empty %}#} {# <p>for循环的对象内部没有值</p>#} {#{% endfor %}#} {#{% for foo in d.keys %}#} {# <p>{{ foo }}</p>#} {#{% endfor %}#} {##} {##} {#{% for foo in d.values %}#} {# <p>{{ foo }}</p>#} {#{% endfor %}#} {##} {#{% for foo in d.items %}#} {# <p>{{ foo }}</p>#} {#{% endfor %}#} {#<p>当一个值获取的步骤非常繁琐 但是又需要在很多地方用到 我们可以用起别名的方式来简化代码</p>#} {#{% with d.hobby.1.username.1 as eg %}#} {# <p>别名只能在with内使用:{{ eg }}</p>#} {# <p>{{ d.hobby.1.username.1 }}</p>#} {#{% endwith %}#} <p>自定义过滤器的使用</p> {% load mytag %} <p>{{ 10|my_sum:90 }}</p> <p>自定义标签的使用</p> {% load mytag %} <p>{% my_baby 1 2 3 'hello world' %}</p> <p>自定义的过滤器可以在逻辑语句中而自定义的标签不可以</p> {% if 10|my_sum:100 %} <p>条件成立</p> {% endif %} {% if my_baby 1 2 3 4 %} <p>条件成立</p> {% endif %} <p>自定义inclusion_tag的使用</p> {% load mytag %} {% myin 5 %} </body> </html>
7.模板继承与导入
模板的继承 某一个页面大部分区域都是公用的 那这个页面就可以作为模板页面 当别人继承这个页面之后 如何修改对应的区域 先在模板页面上通过block实现划定区域 {% block content %} 模板页面内容 {% endblock %} 子页面中先导入整个模板 {% extends '模板页面.html'%} 修改特定的区域 通过实现划定好的区域名称 {% block content %} 子页面内容 {% endblock %} 通常情况下 模板页面页面应该起码有三块区域 {% block css %} 模板页面内容 {% endblock %} {% block content %} 模板页面内容 {% endblock %} {% block js %} 模板页面内容 {% endblock %} # 模板的block块越多 可扩展性越高 还支持子页面调用父页面对应区域的内容 并且可以无限次调用 {{ block.super }} 模板的导入 将html页面当做模块使用 哪里需要导哪里 这个html页面通常都不是完整的 只是一个局部样式 {% include 'left.html' %}
模板页
{% block content %} 标记可以改的部分 对页面没有任何影响
一般模板分三块 css content js
重用父类的内容 super
模板导入 include
先写一个组件页面