说明
本文主要讲解Flask中的过滤器的自定义以及模版的自定义
一、过滤器
过滤器的本质是函数,有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用 Python 中的某些方法,那么这就用到了过滤器。
(一)、flask中自带的过滤器
html中变量的引用:{{ 变量 }}
过滤器的是用方式:{{ 变量 | 过滤器 }}
字符串中的过滤器
length 获取长度
safe 禁止转译,当传递的参数为html页面时使用
capitalize 英文的首字母转大写
lower 将所有的字母转为小写
upper 将所有的字母转为大写
title 将英文中的每个单词的首字母转为大写
reverse 将字符串转为倒序
列表中的过滤器:
first 获取列表中的第一个元素
last 获取列表的最后一个参数
sum 求和
sort 排序
{{ 变量.0 }} 取出列表中下标为0的元素
字典的过滤器:
{{ 字典.values() }} 取出字典中所有的value
{{ 字典.keys() }} 取出字典中所有的key
html中的循环
for循环格式:
{% for 条件 %}...{% endfor %}
if单分支循环格式:
{% if 条件 %}...{% endif %}
if双分支循环格式:
{% if 条件 %}...{% elif 条件 %}....{% endif %}
过滤器使用示例:
app1.py
from flask import Flask, render_template
import settings
app = Flask(__name__)
app.config.from_object(settings) # 加载配置文件,这里需要先创建一个settings.py文件,中间定义相关的配置
@app.route('/show1') # 定义路由为show1
def show1(): # 创建视图函数
girls = ['宋轶', '孙艺珍', '刘亦菲', '林允儿', '金喜善'] # 创建一个列表
users = [
{"username": "test1", "password": "123456", "addr": "深圳", "phone": "12345678900"},
{"username": "test2", "password": "123457", "addr": "上海", "phone": "12345678901"},
{"username": "test3", "password": "123458", "addr": "武汉", "phone": "12345678902"},
{"username": "test4", "password": "123459", "addr": "北京", "phone": "12345678903"},
{"username": "test5", "password": "123450", "addr": "上海", "phone": "12345678904"}
]
msg = '<h1>hello world</h1>' # 创建一个html页面
n1 = "hello" # 普通字符
return render_template("show1.html",girls=girls,users=users, msg=msg, n1=n1)
# 使用render_template加载html文件,并传递参数格式(加载文件名,html中变量=当前变量...)这里定义的是什么变量,在html引用的就是什么变量
# render_template默认加载的templates中的html文件,创建一个flask项目中会有这个文件夹
if __name__ == '__main__':
app.run() # 默认使用的是5000端口
show1.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤器的使用</title>
</head>
<body>
<!--
-->
{{ girls.append('zhangsan') }} 在列表中添加一个元素
{{ girls }}
<br>
当前用户共: {{ girls | length }} 人
<br>
字符串的过滤器:
<br>
{{ msg | safe }} 禁用转译,使标签能够被html解读
<br>
{{ n1 | capitalize }} 首字母大写
<br>
{{ "HELLo" | lower }} 将所有字母转换为小写
<br>
{{ "hello" | upper }} 将所以字母转换为大写
<br>
{{ "this is python" | title }} 英文中每个单词首字母大写
<br>
{{ "this is python" | reverse }} 将字符串倒过来
<br>
列表中过滤器:
<br>
{{ girls | first }} 获取第一个值
<br>
{{ girls | last }} 获取最后一个值
<br>
{{ girls | length }} 获取长度
<br>
{{ [1, 3,4 ,7,2,5] | sum }} ------求和
<br>
{{ [1, 3,4 ,7,2,5] | sort }} ---- 排序
<br>
字典中的过滤器:
<br>
<p>
{{ users.0 }} ---- 取出列表中下标为0的元素
<br>
取出字典的value值:
<br>
{% for i in users.0.values() %}
<p>{{ i }}</p>
{% endfor %}
<br style="background-color: #9C1A1C">
循环取出字典中key对应的vlaue:
<br>
{% for k,v in users.0.items() %}
<p>{{ k }}---{{ v }}</p>
{% endfor %}
</p>
</body>
</html>
创建setttings.py文件
ENV = "development" # 定义环境
DEBUG = True # 定义debug状态,修改代码后会自动重新加载代码
执行app1.py,然后在浏览器中访问
http://127.0.0.1:5000/show1
(二)、自定义过滤器
创建自定义过滤器有两中方法,一种是使用函数,一种是使用装饰器,不管是使用函数还是使用装饰器,都需要创建一个函数
app2.py
from flask import Flask, render_template
import settings
app = Flask(__name__)
app.config.from_object(settings)
@app.route('/')
def index1():
msg = "hello world, hello world"
li = [6, 5, 4, 3, 2, 1]
return render_template('index.html', msg=msg, li=li) # 传参到html文件中,在html中调用变量和装饰器
def re_hello(value): # 第一种,使用函数,自定义过滤器,这里是替换hello为fuck的过滤器
print('------' + value + '---------')
a = value.replace('hello', 'fuck')
print('------' + a + '---------')
return a # 必须要返回替换的结果
app.add_template_filter(re_hello, "hello") # 创建过滤器名字,过滤器名字为hello
# 第二种方式:装饰器,制作一个将列表倒序的过滤器
@app.template_filter('test_list') # 创建过滤器名字为test_list
def reverse_list(li): # 创建过滤器函数
temp_li = list(li)
temp_li.reverse()
return temp_li # 返回值
if __name__ == '__main__':
app.run()
在templates文件夹中创建一个index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义过滤器</title>
</head>
<body>
{{ msg }} {# 引用传入的变量msg #}
<hr>
{{ msg | hello }} {# 使用自定义过滤器hello #}
<hr>
{{ li }}
<hr>
{{ li | test_list }} {# 使用自定义过滤器test_list #}
</body>
</html>
而后关掉app1.py,执行app2.py,在浏览器访问
http://127.0.0.1:5000/
总结:
过滤器的本质就是函数:
1、通过flask模块中的add_template_filter方法
a、定义一个函数、必须要待带参数和返回值
b、添加过滤器 app.add_template_filter(过滤器函数名, ‘过滤器名’), 在过滤器函数下面
c、在模版中调用过滤器 {{ 变量| 自定义过滤器名 }}
2、使用装饰器完成
a、定义一个函数,带参和返回值
b、通过装饰器定义过滤器名 @app.add_template_filter(‘过滤器名’),在过滤器函数上面
c、在模版中调用过滤器 {{ 变量| 自定义过滤器名 }}
二、模版
模版是为减少代码的冗余,将能够复用的代码创建为模版。
模版的复用主要分为三种方式:模版继承、include、宏
使用场景
模版继承使用场景:
1、多个模版具有完全相同的顶部和底部
2、多个模版具有相同的模版内容,但是内容中部分不同
3、多个模版具有完全相同的模版内容
include使用场景
在a、b、c页面共同部分,但是其他页面没有这部分,这个时候可以使用include
1、定义一个公共的模版部分xxxx.html
2、使用include调用公共模版,{% include 'xxxx.html' %}
宏:macro(就是一个函数)
1、把它看作jinja2的一个函数,这个函数可以返回一个html字符串
2、避免重复定义相同代码,代码可复用,避免代码的冗余
(一)、模版继承
模版继承需要先创建一个父模版,然后子模版可以继承父模版中的所有属性和标签
父模版: base.html,在父模版中需要自定以的地方,需要使用
{% block 模版名 %} 代码块 {% endblock %}
定义一个模版名,相当于占位,以便于子模版在继承父模版能够自定义一些内容
在子模版中继承父模版使用
{% extends '父模版文件名' %}
{% block title %}
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}
测试
{% endblock %}
</title>
<!--通过style定义样式,样式的名称是与div中的id一样的-->
<style>
#head{
height: 80px;
color: #444444;
background-color: aqua;
}
#head ul {
list-style: none;
height: 50px;
}
#head li {
float: left;
width: 100px;
text-align: center;
font-size: 18px;
height: 50px;
line-height: 50px;
}
#zj{
height: 900px;
background-color: chartreuse;
}
#dibu{
height: 50px;
line-height: 50px;
background-color: #9C1A1C;
}
</style>
{% block mycss %} {# 创建模版,模版名为mycss #}
{% endblock %}
</head>
<body>
<div id="head">
<ul>
<li>首页</li>
<li>秒杀</li>
<li>超市</li>
<li>会员</li>
<li>游客</li>
</ul>
</div>
<div id="zj">
{% block zj %}
<!--这里是定义一个按钮-->
<button id="btn">我是中间部分</button>
{% endblock %}
<ul>
<li>中间</li>
</ul>
</div>
<div id="dibu"> <!--通过div定义底部标签-->
<ul>
<li>底部</li>
</ul>
</div>
{% block myjs %}
<!--在html中预留模版的位置,为后续子页面继承的时候能够自定义-->
{% endblock %}
</body>
</html>
子模版文件,在子模版中自定义模版时,模版名需要与父模版中的模版名一致
index2.html
{% extends 'base.html' %}
{% block title %} <!--这里是通过extends继承父html中的内容-->
首页
{% endblock %}
{% block mycss %} <!--自定义mycss模版-->
<style>
#head{
background-color: #9C1A1C;
}
#zj{}
.div1{
width: 24%;
height: 500px;
float: left;
border: 1px solid red;
}
.div2{
width: 24%;
height: 500px;
float: left;
border: 1px solid darkblue;
}
.div3{
width: 24%;
height: 500px;
float: left;
border: 1px solid saddlebrown;
}
.div4{
width: 24%;
height: 500px;
float: left;
border: 1px solid #3B666B;
}
</style>
<!---link rel="stylesheet" href="../static/css/styple.css" 也可以这样写,对于外部的样式通过以下的方式进行添加,
如js脚本、css样式,图片,都可以通过这种方式进行添加-->
<link rel="stylesheet" href="{{ url_for('static', filename='css/styple.css') }}">
{% endblock %}
{% block myjs %}
<script>
btn = document.getElementById('btn')
btn.onclick=function(){
alert('别点我!')
}
</script>
{% endblock %}
{% block zj %}
<div class="div1" id="d1">进入百度</div>
<div class="div2" id="d2">xxxx</div>
<div class="div3" id="d3">eee</div>
<img src="{{ url_for('static', filename='imge/u.jpg') }}" alt="">
<!--加载图片-->
{% endblock %}
(二)、include
include模版调用格式:
{% include ‘模版文件’ %}
首先创建一个模版文件
headers.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>头部</title>
</head>
<body>
<div style="height: 50px;background-color: #A5D6D9">
</div>
</body>
</html>
也可以以下,include的原理是将引用的模版文件整个加载到当前文件中
<div style="height: 50px;background-color: #A5D6D9">
通过include调用模版
welcome.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎页面</title>
</head>
<body>
{% include 'headers.html' %}
<div style="background-color: #444444;height: 100px"></div>
</body>
</html>
创建app3.py文件
from flask import Flask, render_template
import settings
app = Flask(__name__)
app.config.from_object(settings)
@app.route('/base')
def load_base(): # 定义一个父模版,模版在html文件中定义
return render_template('base.html')
#
@app.route('/')
def index():
return render_template('index2.html')
@app.route('/welcome')
def welcome():
return render_template('welcome.html')
if __name__ == '__main__':
app.run()