Django之模板层 (变量分配 过滤器 标签 继承和导入 自定义过滤器、标签及inclusion_tag(了解))
目录
一、模板变量分配
定义
在后端变量的值通过模板语法传到前端
-
符号
{{}}:主要与数据值相关
{%%}:主要与逻辑相关 -
模板语法注意点:
1.针对需要加括号调用的名字 django模板语法会自动加括号调用你只需要写名字就行
2.模板语法的注释{##},前端浏览器是无法查看的,因为它要先在后端运行
3.django的模板语法是自己写的 跟jinja2不一样,只能用句点符的方式点出来 -
模板语法两种传值方法
return render(request, 'demo02.html', {'n1': name, 'a1': age}) # 传值方式1:精准传值 不浪费资源 针对多资源的传递书写麻烦
return render(request,'demo02.html', locals()) # 传值方式2:将函数名称空间中所有的名字全部传递 名字过多并且不使用的情况下比较浪费资源
- 模板语法传值特性
1.基本数据类型正常展示
2.文件对象也可以展示并调用方法
3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
4.类名也会自动加括号调用,对象则不用加括号也可以调用(除非用魔法)
ps:总结针对可以加括号调用的名字模板语法都会自动加括号调用
- 代码展示
前端
<p>{{ f }}</p>
<p>{{ i }}</p>
<p>{{ s }}</p>
<p>{{ l }}</p>
<p>{{ d }}</p>
<p>{{ t }}</p>
<p>{{ se }}</p>
<p>{{ b }}</p>
<p>{{ f_obj }}</p>
<p>{{ f_obj.read }}</p>
<!--你能不能看到我-->
你看到了什么 快分享给我看看!!!
<p>{{ func1 }}</p>
<p>{{ MyClass }}</p>
<p>{{ obj }}</p>
<p>{{ obj.get_obj }}</p>
<p>{{ obj.get_cls }}</p>
<p>{{ obj.get_static }}</p>
后端
def func(request):
# python基本数据类型
f = 1.11
i = 666
s = 'hello jason! say hello big baby ha ha ha'
l = [11, 22, 33, 44]
d = {'name': 'jason', 'age': 18}
t = (11, 22, 33, 44)
se = {11, 22, 33, 44}
b = True
# 文件对象
f_obj = open(r'D:\pythonProject03\djangoday04\今日内容.md', 'rb')
# 函数
def func1():
print('上午犯困 下午也犯困 晚上还犯浑')
return '熬夜会上瘾'
# 类
class MyClass(object):
def get_obj(self):
return '绑定给对象的方法'
@classmethod
def get_cls(cls):
return '绑定给类的方法'
@staticmethod
def get_static():
return '静态方法'
obj = MyClass()
页面效果
二、模板的过滤器
定义
模块语法自带的一些内置函数
语法
{{obj|filter__name:param}} 变量名字|过滤器名称:变量
-
default
如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:
{{ value|default:"nothing"}}
- length
返回值的长度。它对字符串和列表都起作用。例如: 如果 value 是 [‘a’, ‘b’, ‘c’, ‘d’],那么输出是 4。
{{ value|length }}
- filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:如果 value 是 123456789,输出将会是 117.7 MB
{{ value|filesizeformat }}
- date
如果 value=datetime.datetime.now()
{{ value|date:"Y-m-d"}}
- slice
如果 value=”hello world”,将会是llo worl
{{ value|slice:"2:-1"}}
- truncatechars
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“…”)结尾。参数:要截断的字符数
{{ value|truncatechars:9}}
- safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
value="<a href="">点击</a>"
{{ value|safe}}
from django.utils.safestring import mark_safe
res = mark_safe('<h1>HELLO WORLD</h1>')
- 代码展示
前端
<p>{{ i|add:10 }}</p>
<p>{{ s|add:'baby' }}</p>
<p>{{ l|length }}</p>
<p>{{ s|slice:'1:4' }}</p>
<p>{{ value|slice:"2:-1"}}</p>
<p>{{ s|truncatechars:5 }}</p>
<p>{{ s|truncatewords:3 }}</p>
<p>{{ ctime|date:'Y年-m月-d日 H时:i分:s秒 ' }}</p>
<p>{{ file_size|filesizeformat }}</p>
<p>{{ h1|safe }}</p>
<p>{{ s1|safe }}</p>
后端
def func(request):
from datetime import date,datetime
ctime = datetime.today()
import os
file_size = 424232423423432
h1 = '<h1>哈哈哈哈</h1>'
s1 = "<script>confirm(123)</script>"
return render(request, 'funcPage.html', locals())
页面效果
三、模板之标签
- if标签
在html页面if ,然后tab键补全
语法
{% if 条件1(可以自己写也可以用传递过来的数据) %}
<p>今天又是周三了</p>
{% elif 条件2(可以自己写也可以用传递过来的数据) %}
<p>百日冲刺</p>
{% else %}
<p>没多少时间了!</p>
{% endif %}
- for标签
在html页面for ,然后tab键补全
语法
{% for k in t1 %}
{% if forloop.first %}
<p>这是我的第一次循环{{ k }}</p>
{% elif forloop.last %}
<p>这是我的最后一次循环{{ k }}</p>
{% else %}
<p>这是中间循环{{ k }}</p>
{% endif %}
{% empty %}
<p>你给我传的数据是空的无法循环取值(空字符串、空列表、空字典)</p>
{% endfor %}
- forloop关键字
# 遍历字典
# 字典的三剑客
keys values items
forloop.counter The current iteration of the loop (1-indexed) 当前循环的索引值(从1开始)
forloop.counter0 The current iteration of the loop (0-indexed) 当前循环的索引值(从0开始)
forloop.revcounter The number of iterations from the end of the loop (1-indexed) 当前循环的倒序索引值(从1开始)
forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) 当前循环的倒序索引值(从0开始)
forloop.first True if this is the first time through the loop 当前循环是不是第一次循环(布尔值)
forloop.last True if this is the last time through the loop 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环
ps: django模板语法取值操作>>>:只支持句点符,句点符既可以点索引也可以点键
d1 = {'name': 'jason', 'age': 18, 'hobby': ['read', 'music', {'a1': 'haha', 'a2': 'heihei'}]}
{{ d1.hobby.2.a1 }}
- 起别名
复杂数据获取之后需要反复使用可以起别名
{% with d1.hobby.2.a1 as h %}
<a href="">{{ h }}</a>
{% endwith %}
四、自定义过滤器、标签及inclusion_tag(了解)
- 前期准备工作
如果想要自定义一些模板语法 需要先完成下列的三步走战略
1.在应用下创建一个名字必须叫templatetags的目录
2.在上述目录下创建任意名称的py文件
3.在上述py文件内先编写两行固定的代码
from django import template
register = template.Library()
- 自定义过滤器(最大只能接收两个参数)
@register.filter(name='myadd')
def func1(a, b):
return a + b
目前编辑的页面代码
{% load mytags %} # 加载自己创建的py文件
<p>{{ i|myadd:1 }}</p>
- 自定义标签(参数没有限制)
@register.simple_tag(name='mytag')
def func2(a, b, c, d, e):
return f'{a}-{b}-{c}-{d}-{e}'
目前编辑的页面代码
{% load mytags %} # 加载自己创建的py文件
{% mytag 'jason' 'kevin' 'oscar' 'tony' 'lili' %}
- 自定义inclusion_tag(局部的html代码)
调用函数,在一个自己新建的空html文件中执行,执行完后再塞进需要用的html页面
@register.inclusion_tag('menu.html',name='mymenu')
def func3(n):
html = []
for i in range(n):
html.append('<li>第%s页</li>'%i)
return locals()
新建的借助menu.html页面代码
<ul>
{% for liStr in html %}
{{ liStr|safe }}
{% endfor %}
</ul>
目前编辑的页面代码
{% load mytags %} # 加载自己创建的py文件
{% mymenu 20 %}
五、模板的继承和导入
模板的继承(重要)
定义
多个页面有很多相似的地方 我们可以采取下列方式
- 方式1:传统的复制粘贴
- 方式2:模板的继承
1.在模板中使用block划定子板以后可以修改的区域
{% block 区域名称 %}
继承的旧代码区域
{% endblock %}
2.子板继承模板
{% extends 'home.html' %} # 首先要先导入母版
{% block 区域名称 %}
继承的新代码区域
{% endblock %}
补充:子板也可以继续使用模板的内容
{{ block.super }}
ps:模板中至少应该有三个区域,分别是页面内容区、css样式区、js代码区
模板的导入(了解)
定义
将某个html的部分提前在一个空的html页面写好 之后很多html页面都想使用就可以导入,在需要导入的地方
{% include 'myform.html' %}
直接上代码,以后可以粘贴复制
- 母板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{# <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>#}
{# <link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.css">#}
{# <script src="bootstrap-3.4.1-dist/js/bootstrap.js"></script>#}
{% load static %}
<script src="{% static 'jquery.min.js' %}"></script>
<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>
<style>
.c1 {
float: left;
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse">
<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">羊村登录管理系统</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">模块</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="#">链接<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">下载 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">版本</a></li>
<li><a href="#">其他活动</a></li>
<li><a href="#">其他一些好玩的</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">点击有惊喜</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">不信点这里</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 class="container-fluid">
<div class="row">
<div class="col-lg-4">
<!-- Single button -->
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
Action <span class="caret"></span>
</button>
<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>
</div>
<div class="list-group">
<a href="#" class="list-group-item disabled">
网页基本功能
</a>
<a href="/child1/" class="list-group-item">登录</a>
<a href="/child2/" class="list-group-item">注册</a>
<a href="#" class="list-group-item">编辑</a>
<a href="#" class="list-group-item">删除</a>
</div>
<ul class="list-group">
<li class="list-group-item list-group-item-success">Dapibus ac facilisis in</li>
<li class="list-group-item list-group-item-info">Cras sit amet nibh libero</li>
<li class="list-group-item list-group-item-warning">Porta ac consectetur ac</li>
<li class="list-group-item list-group-item-danger">Vestibulum at eros</li>
</ul>
<div class="list-group">
<a href="#" class="list-group-item list-group-item-success">青青草原第一飞毛腿-喜哥</a>
<a href="#" class="list-group-item list-group-item-info">青青草原第一睡神-懒哥</a>
<a href="#" class="list-group-item list-group-item-warning">青青草原第一美女-美姐</a>
<a href="#" class="list-group-item list-group-item-danger">青青草原第一帅哥-狼哥</a>
</div>
<nav aria-label="...">
<ul class="pagination">
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a>
</li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
<li class="active"><a href="#">2 <span class="sr-only">(current)</span></a></li>
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a>
</li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a>
</li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a>
</li>
<li class="active"><a href="#">1 <span class="sr-only">(current)</span></a></li>
</ul>
</nav>
</div>
<div class="col-lg-8">
{% block content %}
<div class="panel panel-warning">
<div class="jumbotron">
<h1>这里青青草原的网页</h1>
<p>里面记录着羊村和狼堡的信息</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">了解羊村</a></p>
</div>
</div>
<div class="panel panel-success">
<div class="row">
<div class="col-xs-6 col-md-3">
<a href="#" class="thumbnail">
<img src="https://img1.baidu.com/it/u=1682278568,1662583579&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"
alt="...">
</a>
</div>
<div class="col-xs-6 col-md-3">
<a href="#" class="thumbnail">
<img src="https://img1.baidu.com/it/u=1236718530,2234744473&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=505"
alt="...">
</a>
</div>
<div class="col-xs-6 col-md-3">
<a href="#" class="thumbnail">
<img src="https://img2.baidu.com/it/u=660177652,3207960518&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"
alt="...">
</a>
</div>
<div class="col-xs-6 col-md-3">
<a href="#" class="thumbnail">
<img src="https://img1.baidu.com/it/u=4028757630,2942084939&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=499"
alt="...">
</a>
</div>
</div>
<div class="panel panel-info">
<div class="row">
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<img src="https://img1.baidu.com/it/u=259115010,423465834&fm=253&fmt=auto&app=138&f=PNG?w=500&h=565"
alt="...">
<div class="caption">
<h3>武大狼的第250代子孙,第77代狼王,自称“本大王”,喜羊羊等人也称他为“灰太狼大王”。疼爱孩子的好丈夫、好爸爸。</h3>
<p>...</p>
<p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#"
class="btn btn-default"
role="button">Button</a>
</p>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<img src="https://img1.baidu.com/it/u=2822434814,2828561864&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=427"
alt="...">
<div class="caption">
<h3>
黑大帅,动画片《喜羊羊与灰太狼》系列中的反派角色,后来成为正面角色,初登场于动画《喜羊羊与灰太狼之古古怪界大作战》第4集(即《喜羊羊与灰太狼》第一部第284集)作为反派角色,来自地底下的古古怪界。</h3>
<p>...</p>
<p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#"
class="btn btn-default"
role="button">Button</a>
</p>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<img src="https://img2.baidu.com/it/u=2970440372,1083416465&fm=253&fmt=auto&app=138&f=JPEG?w=572&h=500"
alt="...">
<div class="caption">
<h3>
武泰哥,又称老虎大叔。为国产动画片《喜羊羊与灰太狼》系列中出现的人物,原型是一只金黄色的华南虎,四臂有健壮的肌肉,胸部点缀着两大块胸肌。常常举行肌肉展示,包包大人为他伤透了脑筋。 </h3>
<p>...</p>
<p><a href="#" class="btn btn-primary" role="button">Button</a> <a href="#"
class="btn btn-default"
role="button">Button</a>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-warning">...</div>
<div class="panel panel-danger">...</div>
</div>
</div>
{% endblock %}
</div>
</div>
</body>
</html>
- 子板1
{% extends 'Monpage.html' %}
{% block css %}
<style>
#d2 {
color: yellow;
}
</style>
{% endblock %}
{% block content %}
<h1 class="text-center" id="d2">登录页面</h1>
{% include 'daoru.html' %}
<form action="">
<p>username:
<input type="text" class="form-control">
</p>
<p>password:
<input type="text" class="form-control">
</p>
<input type="submit" class="btn btn-warning btn-block">
</form>
{% endblock %}
{% block js %}
<script>alert('注册页面')</script>
{% endblock %}
- 子板2
{% extends 'Monpage.html' %}
{% block css %}
<style>
#d2 {
color: yellow;
}
</style>
{% endblock %}
{% block content %}
<h1 class="text-center" id="d2">注册页面</h1>
{% include 'daoru.html' %}
<form action="">
<p>username:
<input type="text" class="form-control">
</p>
<p>password:
<input type="text" class="form-control">
</p>
<input type="submit" class="btn btn-warning btn-block">
</form>
{% endblock %}
{% block js %}
<script>alert('注册页面')</script>
{% endblock %}
- 母板页面效果
- 子板页面效果