django模板层详解
模板层
内容概要
- 模板层传值
- 模板层过滤器
- 模板层标签
- 自定义过滤器,标签及inclusion_tag(了解)
- 模板的继承与导入
{{}}:主要是与数据值相关
{%%}:主要与逻辑相关
django的模板语法是自己写的 跟jinja2不一样
-
针对需要加括号调用的名字 django模板语法会自动加括号调用,我们只需要写名字就行
-
模板语法的注释前端浏览器是无法查看的
{#注释内容#}
-
模板语法传值
- 传值方式1精准传值,不浪费资源怎对多资源的传递书写麻烦
return render(request, 'demo02.html', {'n1': name, 'a1': age})
-
传值方式2将函数名称空间中所有的名字全部传递 名字过多并且不使用的的情况下比较浪费资源
return render(request, 'demo02.html', locals())
-
模板语法传值特性
-
基本数据类型正常展示
-
文件对象也可以正常展示并调用
-
函数名会自动加括号执行将返回值展示到页面上(不支持额外传参)
-
类名也会自动加括号调用
-
对象则不会
-
总结针对可以加括号调用的名字模板语法都会自动加括号调用
def template_test(request): l = [11, 22, 33] d = {"name": "alex"} class Person(object): def __init__(self, name, age): self.name = name self.age = age def dream(self): return "{} is dream...".format(self.name) Alex = Person(name="Alex", age=34) jason = Person(name="jason", age=9000) Eva_J = Person(name="Eva_J", age=18) person_list = [Alex, jason, Eva_J] return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})
{# 取l中的第一个参数 #} {{ l.0 }} {# 取字典中key的值 #} {{ d.name }} {# 取对象的name属性 #} {{ person_list.0.name }} {# .操作只能调用不带参数的方法 #} {{ person_list.0.dream }}
-
模板语法过滤气器(相当于内置函数)
https://www.cnblogs.com/Dominic-Ji/articles/10982302.html详细的过滤器参考这里
过滤器 | 用法 | 代码 |
---|---|---|
last | 获取列表/元组的最后一个成员 | {{liast | last}} |
first | 获取列表/元组的第一个成员 | {{list|first}} |
length | 获取数据的长度 | {{list | length}} |
defualt | 当变量没有值的情况下, 系统输出默认值, | {{str|default="默认值"}} |
safe | 让系统不要对内容中的html代码进行实体转义 | {{htmlcontent| safe}} |
upper | 字母转换成大写 | {{str | upper}} |
lower | 字母转换成小写 | {{str | lower}} |
title | 每个单词首字母转换成大写 | {{str | title}} |
date | 日期时间格式转换 | `{{ value |
cut | 从内容中截取掉同样字符的内容 | {{content | cut:"hello"}} |
list | 把内容转换成列表格式 | {{content | list}} |
add | 加法 | {{num| add}} |
filesizeformat | 把文件大小的数值转换成单位表示 | {{filesize | filesizeformat}} |
join |
按指定字符拼接内容 | {{list| join("-")}} |
random |
随机提取某个成员 | {list | random}} |
slice |
按切片提取成员 | {{list | slice:":-2"}} |
truncatechars |
按字符长度截取内容 | {{content | truncatechars:30}} |
truncatewords |
按单词长度截取内容 | 同上 |
模板层标签(模板的流程控制)
if else分支
{% if 1 %}
<h1>if条件成立执行代码</h1>
{% else %}
<h1>if条件不成执行的代码</h1>
{% endif %}
if elif else分支
{% if 0 %}
<h1>条件1成立执行</h1>
{% elif 1 %}
<h1>条件1不成立条件2成立执行</h1>
{% else %}
<h1>条件1条件2都不成立执行</h1>
{% endif %}
for循环
{% for foo in li %}
<p> {{ foo }}</p>
{% endfor %}
{% for foo in li %}
{% if forloop.first %} # forloop.first判断是不是第一个数据
first: {{ foo }}
{% elif forloop.last %} # forloop.first判断是不是最后一个数据
last: {{ foo }}
{% else %}
middle: {{ foo }}
{% endif %}
{% for foo in li %}
<p>{{ forloop }}</p>
{% endfor %}
空字符串、空列表、空字典无法循环取值
#views.py
def index_func(request):
li = [1, 2, 3, 4, 5, 6, 7, 8, 9]
d1 = {}
return render(request, 'index.html',locals())
# index.html
{% for foo in d1 %}
{% if forloop.first %}
哈哈哈
{% endif %}
坤坤坤
{% empty %}
空的值,什么都没传
{% endfor %}
django模板语法取值操作:只支持句点符
句点符既可以点索引也可以点键
<p>{{ d2.name }}</p>
<p>{{ d2.age }}</p>
<p>{{ d2.hobby.1 }}</p>
复杂数据获取之后需要反复使用的可以起别名
{% with d2.hobby.0 as hb %}
<p>{{ hb }}</p>
<p>爱好:{{ hb }}</p>
{% endwith %}
自定义过滤器、标签及inclusion_tag(了解)
如果想要自定义一些模板语法,需要先完成下列的三个必要步骤
同一个文件内的自定义过滤器,标签,以及inclusion_tag只需要load一次,下面代码不需要再加载
{% load tags %}
-
在
应用
(需要注意是应用下,不是项目根目录)下创建一个名字必须叫templatetags的目录 -
在上述目录下创建任意名称的py文件
-
在上述py文件内先编写两行固定代码
自定义过滤器最大只能接收两个参数
from django import template register = template.Library() # 并且register这个变量名也必须一样,否则不能正常加载 @register.filter(name='mytags') def func(data, mydata): return data + mydata + 10
{% load tags %} <p>{{ li.1|mytags:li.2 }}</p>
小案例自定义取余
@register.filter(name='quyu') def qu_func(data): if data % 2 == 0: return True return False {% load tags %} <p> {% if li.1|quyu %} 可以被2整除的 {{ li.1 }} {% else %} 不可被二整除的 {{ li.1 }} {% endif %} </p>
自定义标签(参数没有限制),也需要遵守上面三个必要步骤
from django import template
register = template.Library()
@register.simple_tag(name='mytt')
def func(var1, var2, var3, var4):
var4 = str(var4)
return f'哈哈哈{var1, var2, var3, var4}'
{% load tags %}
{#中文必须要用字符串包裹,传递数据必须是字符型或整数,浮点型,#}
{#而且参数与形参必须一致#}
<p>{% mytt '张三' 1 2.2 "['1','2','3']" %}</p>
自定义inclusion_tag(局部的html代码)
#tags.py
@register.inclusion_tag('menu.html', name='menu')
def func2(n):
html = []
for i in range(n):
html.append(f'<p>{i}</>')
return locals()
#menu.html
哈哈哈哈哈
{% for foo in html %}
{{ foo|safe }}
{% endfor %}
#index.html
{% load tags %}
{% menu 5 %}
模板的继承与导入
模板的继承(重要)
多个页面有很多相似的地方 我们可以采取下列方式
方式1:传统的复制粘贴
方式2:模板的继承
-
在模板中使用block划定子板以后可以修改
模板页<div class="container"> <div class="row"> <div class="col-md-2 col-md-offset-1"> <div class="list-group"> <a href="/" class="list-group-item active">主页</a> <a href="/login/" class="list-group-item ">登录</a> <a href="/register/" class="list-group-item">注册</a> </div> </div> <div class="col-md-8"> <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> {% block nav %} {# 这里是划定子页面可以修改的取余#} <div class="page-header"> <h1>嗨嗨嗨 <small>老八秘制小汉堡</small></h1> </div> {% endblock %} </div> </div> </div>
子页面继承
{#继承模板页面#} {% extends 'nav.html' %} {#对模板页面允许修改的地方进行修改#} {% block nav %} <form action="" > <p>name:<input type="text" class="form-control"></p> <p>password:<input type="password" class="form-control"></p> <input type="submit" value="登录" class="form-control"> </form> {% endblock %}
子页面继承模板页面并,调用模板页面的可以修改内容
{#继承模板页面#} {% extends 'nav.html' %} {#对模板页面允许修改的地方进行修改#} {% block nav %} {# 调用模板页面的可修改内容#} {{ block.super }} <form action="" > <p>name:<input type="text" class="form-control"></p> <p>password:<input type="password" class="form-control"></p> <p>gender <input type="radio" name="gender">male <input type="radio" name="gender">female <input type="radio" name="gender">other </p> <input type="submit" value="注册" class="form-control"> </form> {# 调用模板页面的可修改内容#} {{ block.super }} {% endblock %}
模板中至少应该三个区域
页面内容区、css样式区、js代码区
{% block css %}
{# 这里是划定子页面可以修改的#}
#划定给css的
{% endblock %}
{% block html %}
{# 这里是划定子页面可以修改的#}
#划定给html的
{% endblock %}
{% block js %}
{# 这里是划定子页面可以修改的#}
#划定给js的
{% endblock %}
模板的导入(了解)
将某个html的部分提前写好 之后很多html页面都想使用就可以导入
<div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%">
<span class="sr-only">40% Complete (success)</span>
</div>
</div>
{% include 'temp.html' %}