Django-模板层
目录
-模板语法
{{ }} : 变量相关
{% %} : 逻辑相关
--传值与取值
模板语法能把后端所有数据类型及函数、类等传到前端,会自动识别前端数据中能加括号调用的函数或类进行调用,但函数或类中不能有参数(模板语法固定不支持传参,所以针对有形参传入的干脆不加括号执行)
模板语法只能通过"句点符"即"."取值,不管是.键还是.索引,反正就只支持.取值,且两者可混用
views.py see_template()
# 模板语法传值给前端页面研究 def see_template(request): i = 666 f = 11.11 b = True s = 'weer' l = ['weer', 'xueer', 'yuner'] t = (111, 222, 333) d = {'name':'weer', 'age':18, 'hobby':['python', 'IT', {'wife':'yunyun'}]} se = {1, 2, 3, 4} def func(): # 不能是有形参的函数,否则前端干脆不执行 return '函数结果' class MyClass(): def class_func(self): return '类中函数返回结果' obj = MyClass() return render(request, 'html02 模板语法传值.html', locals())
html02 模板语法传值.html
<p>{{ i }}</p> <p>{{ f }}</p> <p>{{ b }}</p> <p>{{ s }}</p> <p>{{ l }}</p> <p>{{ t }}</p> <p>{{ d }}</p> <p>{{ se }}</p> <p>{{ func }}</p> <p>自动加括号调用,返回的是一个类的结果对象{{ MyClass }}</p> <p>类实例化得到的对象:{{ obj }}</p> <p>类中方法class_func返回结果:{{ obj.class_func }}</p> {# 模板语法取值 #} <p>{{ l.1 }}</p> <p>{{ d.hobby.2.wife }}</p>
结果
666 11.11 True weer ['weer', 'xueer', 'yuner'] (111, 222, 333) {'name': 'weer', 'age': 18, 'hobby': ['python', 'IT', {'wife': 'yunyun'}]} {1, 2, 3, 4} 函数结果 自动加括号调用,返回的是一个类的结果对象:<app01.views.see_template.<locals>.MyClass object at 0x000001E24C50AEF0> 类实例化得到的对象:<app01.views.see_template.<locals>.MyClass object at 0x000001E24C55E3C8> 类中方法class_func返回结果:类中函数返回结果 xueer yunyun
--过滤器
过滤器就类似于"内置方法",Django中有60多个过滤器,先只介绍10多个,后面用到再去学习记忆
---语法
{{ 数据|过滤器:参数 }} 注:过滤器最多只能传2个参数!!!
---使用示例
views.py filter_use()
def filter_use(request): i = 666 f = 11.11 b = False file_size = 1024 # 假定文件大小 h1 = '<h1>转义标题</h1>' script_back = '<script>alert(123)</script>' s = 'weer喜欢学Python,喜欢看动画,最喜欢不良人、凡人等,国漫yyds' words = 'weer love wives that are yuner xueer and so on' l = ['weer', 'xueer', 'yuner', 'shasha', 'linger', 'yunxi'] t = (111, 222, 333) d = {'name':'weer', 'age':18, 'hobby':['python', 'IT', {'wife':'yunyun'}]} se = {1, 2, 3, 4} import datetime current_time = datetime.datetime.now() from django.utils.safestring import mark_safe res = mark_safe('<h1>后端转义方法</h1>') return render(request, 'html03 模板语法之过滤器and标签.html', locals())
html03 模板语法之过滤器and标签.html
<body> <h1 class="text-center">过滤器使用</h1> <p>统计长度:{{ s|length }}</p> <!--字符串--> <p>统计长度:{{ l|length }}</p> <!--列表--> <p>默认值:{{ b|default:'weer' }}</p> <!--当参数表示为True时显示它,当其表示为False时显示default冒号后面的值--> <p>默认值:{{ i|default:888 }}</p> <!--i=666表示True,故显示666而不是888--> <p>文件大小(自动换算成KB/MB/GB):{{ file_size|filesizeformat }}</p> <p>日期格式化:{{ current_time|date:'Y-m-d H-i-s' }}</p> <!--不用带%了--> <p>切片操作(支持步长):{{ l|slice:'0:4:2' }}</p> <p>切取字符:{{ s|truncatechars:15 }}</p> <!--包含三个点在内--> <p>切取单词:{{ words|truncatewords:7 }}</p> <!--按照空格切,不包含三个点--> <p>移除特定字符:{{ s|cut:'yyds' }}</p> <!--移除字符后显示移除完的内容,不影响原内容--> <p>拼接操作之join:{{ l|join:'$' }}</p> <!--将列表拼接成字符串--> <p>拼接操作之add:{{ i|add:222 }}</p> <!--add可拼加数字--> <p>拼接操作之add:{{ s|add:words }}</p> <!--add也能拼接字符串--> <p>转义:{{ h1 }}</p> <!--默认不识别后端的前端代码--> <p>转义:{{ h1|safe }}</p> <p>转义:{{ script_back|safe }}</p> <p>后端转义:{{ res }}</p> </body>
PS:前后端转义意味着后端也能写前端代码,即先在后端写好再传到前端
--标签
这的"标签"指的是一些流程控制语句
---for循环
先看for循环中的一个变量:forloop:
{% for foo in l %} <p>{{ forloop }}</p> {% endfor %}
{% for foo in l %} <p>{{ foo }}</p> {% endfor %}
---if判断
{% if i > 222 %} <p>666</p> {% elif i < 666 %} <p>888</p> {% else %} <p>999</p> {% endif %}
{% for foo in lll %} {% if forloop.first %} <p>这是我的第一次</p> {% elif forloop.last % } <p>这是最后一次啊</p> {% else %} <p>{{ foo }}</p> {% empty %} <p>for循环的对象中没有元素,无法循环</p> {% endfor %}
---with
{% with d.hobby.3.info as nb %} <p>{{ nb }}</p> <p>在with语法内就可以通过后面的别名快速使用到前面靠非常复杂的方式获取到的数据了</p> <p>{{ d.hobby.3.info }}</p> <!--复杂获取--> {% endwith %}
--自定义过滤器、标签,inclusion_tag
---步骤
1.在应用文件夹下创建一个名字必须为"templatetags"文件夹
2.在该文件夹下创建任意名称的.py文件 (即用来写自定义…的文件) eg:mytag1.py
3.在该py文件内必须先写两句话(必须一字不差):
from django import template
register = template.Library()
之后才能在该.py文件中写自定义标签、过滤器、inclusion_tag(先用@register…语法声明)
使用时都需要先加载该.py文件: {% load mytag1 %}
---自定义过滤器
定义: @register.filter(name='add_int') def func1(int1, int2): # !!!函数形参最多2个 return int1 + int2 使用: {% load mytag01 %} <p>自定义过滤器简单使用:{{ i|add_int:222 }}</p>
---自定义标签
定义: @register.simple_tag(name='wife') def show_wife(x1, x2, x3, x4): # 可传多个参数 return 'wives: %s-%s-%s-%s' % (x1, x2, x3, x4) 使用: {% load mytag01 %} <p>{% wife 'yuner' 'xueer' 'shasha' 'xuner' %}</p> 参数彼此用空格隔开就行
---inclusion_tag
多用于返回html代码片段
先定义一个方法
在页面上调用该方法,并且可以传值
该方法会生成一些数据然后传递给一个html页面
之后将渲染好的结果放到调用的位置
示例
templatetags/my_inclusion.py
from django import template register = template.Library() @register.inclusion_tag('result.html') def show_results(n): n = 1 if n < 1 else int(n) data = ["第{}项".format(i) for i in range(1, n+1)] return {"data": data}
templates/result.html
<ul> {% for choice in data %} <li>{{ choice }}</li> {% endfor %} </ul>
templates/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>inclusion_tag test</title> </head> <body> {% load inclusion_tag_test %} {% show_results 10 %} </body> </html>
-模板的继承
对一些网站,整体布局有相同的地方,比如只有右下方内容在变,而导航条和左侧面板都没变的这种网站,就可能用到了模板的继承
模板继承:选定一个想要继承的母页面继承即可: {% extend 'mother.html'%}
继承母页面的子页面和母页面是一样的,要想在母页面的基础上修改使其称为子页面,需要事先在母页面中用block划分区域并起名,然后在子页面上指明要修改的区域做修改即可
一般一个html文件至少应该有三个可被修改区域:
css区域 js区域 html(body)区域
--使用示例
html05 模板语法之继承 母页面.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板继承</title> <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css"> <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script> </head> <body> <div class="container-fluid"> <div> <!--顶部导航条--> <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> </div> <div class="row"> <div class="col-md-3"> <!--左侧--> <ul class="nav nav-pills nav-stacked"> <li role="presentation"><a href="/inherit/">首页</a></li> <li role="presentation"><a href="/login/">登录</a></li> <li role="presentation"><a href="/register/">注册</a></li> </ul> </div> <div class="col-md-9"> <!--右侧--> {% block content %} <div class="jumbotron"> <h1>Hello, world!</h1> <p>...</p> <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p> </div> {% endblock %} </div> </div> </div> </body> </html>
html05 模板语法之继承 子页面1 登录.html
{% extends 'html05 模板语法之继承 母页面.html' %} {% block content %} <div> <h1 class="text-center">登录</h1> <form action=""> <p>username:<input type="text" class="form-control"></p> <p>password:<input type="password" class="form-control"></p> <input type="submit" class="btn btn-success btn-block" value="登录"> </form> {% include 'html06 模板语法之导入.html' %} </div> {% endblock %}
html05 模板语法之继承 子页面2 注册.html
{% extends 'html05 模板语法之继承 母页面.html' %} {% block content %} <div> <h1 class="text-center">注册</h1> <form action=""> <p>username:<input type="text" class="form-control"></p> <p>password:<input type="password" class="form-control"></p> <input type="submit" class="btn btn-danger btn-block" value="注册"> </form> {% include 'html06 模板语法之导入.html' %} </div> {% endblock %}
views.py
def inherit(request): return render(request, 'html05 模板语法之继承 母页面.html') def login(request): return render(request, 'html05 模板语法之继承 子页面1 登录.html') def register(request): return render(request, 'html05 模板语法之继承 子页面2 注册.html')
urls.py
# 模板语法之继承 path('inherit/', views.inherit), # 登录 path('login/', views.login), # 注册 path('register/', views.register),
-模板的导入
--含义
就是将一个页面当做一个局部,若其他很多html页面都需使用到它,则可以以导模块的形式在前端代码中导入该文件
就相当于把该页面代码塞到导入代码那块
--使用
templates文件夹下有一个'html06 模板语法之导入.html'文件,里面内容是一张图片 若想在上面的继承案例中的注册和登录下使用该文件: {% extends 'html05 模板语法之继承 母页面.html' %} {% block content %} <div> <h1 class="text-center">登录</h1> <form action=""> <p>username:<input type="text" class="form-control"></p> <p>password:<input type="password" class="form-control"></p> <input type="submit" class="btn btn-success btn-block" value="登录"> </form> {% include 'html06 模板语法之导入.html' %} # 导入使用 </div> {% endblock %}