Flask学习

Flask学习

Flask 是一个微型的 Python 开发的 Web 框架,基于Werkzeug WSGI工具箱和Jinja2 模板引擎。 Flask使用BSD授权。 Flask也被称为“microframework”,因为它使用简单的核心,用extension增加其他功能。Flask没有默认使用的数据库、窗体验证工具。然而,Flask保留了扩增的弹性,可以用Flask-extension加入这些功能:ORM、窗体验证工具、文件上传、各种开放式身份验证技术。

第一个Flask程序

该程序比较简单,可对照注释理解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#导入flask扩展
from flask import Flask, render_template

#2.创建Flask应用程序实列
app = Flask(__name__)

#3.定义路由及视图函数
@app.route('/')
def index():
return 'hello world'

#4.启动程序
if __name__ == '__main__':
app.run()

运行后可在http://127.0.0.1:5000/ 即可查看其运行效果。

路由请求方式限定

路由默认只支持GET,如果需要增加,需要自行指定

1
2
3
4
5
6
7
8
9
10
11
from flask import Flask, render_template

app = Flask(__name__)

#路由默认只支持GET,如果需要增加,需要自行指定
@app.route('/', methods=['GET', 'POST'])
def index():
return 'hello world'

if __name__ == '__main__':
app.run()

可以使用[postman][https://www.postman.com/]进行验证

路由参数处理

可以看到我们平时使用百度关键词搜索其实就是通过路由传参的.

下面就是传入参数的路由写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
return 'hello world'

#使用统一视图函数来显示不同用户的订单信息
#<>定义路由参数,<>内需要定义变量名
#参数类型默认是一个字符串
@app.route('/order/<order_id>')
def get_older_id(order_id):
return "orlder_id:%s" % order_id

if __name__ == '__main__':
app.run()

运行结果:

有时需要对传入参数进行限定(比如传入参数只能是数字,当然原始参数都是字符串类型)

对传入参数进行限定:

1
@app.route('/order/<int:order_id>')

此时输入字母就不能正常访问了

Jinja2模板引擎

如何返回一个网页?

再工程文件的templates文件夹下添加一个html页面

html页面代码:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello HTML</h1>
</body>
</html>

更改视图函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#导入render_templatek扩展
from flask import Flask, render_template

app = Flask(__name__)

#返回模板文件
@app.route('/', methods=['GET', 'POST'])
def index():
return render_template('index.html')
#return 'hello world'

@app.route('/order/<int:order_id>')
def get_older_id(order_id):
return "orlder_id:%s" % order_id

if __name__ == '__main__':
app.run()

最终效果图:

向模板传入参数

模板往往不是一个静态的html页面,一些内容需要动态获取,这里通过路由参数传入模板。

Flask代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/<name>')
def index(name):
return render_template('index.html', name = name)#传入参数name

@app.route('/order/<int:order_id>')
def get_older_id(order_id):
return "orlder_id:%s" % order_id

if __name__ == '__main__':
app.run()

在html页面中使用参数,使用一堆花括号括起来使用,这种语法叫做变量代码块

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello HTML</h1>
{#下面是变量代码块的使用#}
<h1>hello {{ name }}<br></h1>
</body>
</html>

最终运行结果:

意外发现的html小技巧:crtl + / 可以快速注释(pycharm)

变量代码块的基本使用

传入列表、字典

除了可以传入简单的字符串之外,python的列表和字典也可以传入,在html中的使用和python中也是相同的。

flask代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/<name>')
def index(name):
name_list = ['Alice', 'Bob', 'Jack']
age_dist = {'Alice': 5,'Bob': 6, 'Jack':7}
return render_template('index.html',
name = name,
name_list = name_list,
age_dist = age_dist
)

@app.route('/order/<int:order_id>')
def get_older_id(order_id):
return "orlder_id:%s" % order_id

if __name__ == '__main__':
app.run()

模板代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello HTML</h1>
{#下面是变量代码块的使用#}
<h1>hello {{ name }}<br></h1>
{#变量代码块中的字典的使用#}
<h2>列表:{{ name_list }}</h2>
<h3>列表中的元素:{{ name_list[0] }} {{ name_list[1] }} {{ name_list[2] }} </h3>
<h2>字典:{{ age_dist }}</h2>
<h3>字典中的元素:{{ age_dist['Alice'] }}</h3>
</body>
</html>

最后的效果:

控制代码块的基本使用

这里简要介绍for循环和if条件判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello HTML</h1>
{#下面是变量代码块的使用#}
<h1>hello {{ name }}<br></h1>
{#变量代码块中的字典的使用#}
<h2>列表:{{ name_list }}</h2>
<h3>列表中的元素:{{ name_list[0] }} {{ name_list[1] }} {{ name_list[2] }} </h3>
<h2>字典:{{ age_dist }}</h2>
<h3>字典中的元素:{{ age_dist['Alice'] }}</h3>
<hr>
{#控制代码块的使用#}
{% for name in name_list %}
{% if name == 'Alice' %}
<h2>{{ name }}的年龄是:{{ age_dist[name] }}</h2>
{% endif %}
{% endfor %}

</body>
</html>

输出结果

过滤器

过滤器的本质就是函数,有时候不仅仅直接使用变量的值,需要修改变量的显示或是格式化、运算等等,但是在模板中又不能直接调用python中的一些方法,所以就用到了过滤器。(使用语法类似于Linux命令行中管道)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello HTML</h1>
{#下面是变量代码块的使用#}
<h1>hello {{ name }}<br></h1>
{#变量代码块中的字典的使用#}
<h2>列表:{{ name_list }}</h2>
<h3>列表中的元素:{{ name_list[0] }} {{ name_list[1] }} {{ name_list[2] }} </h3>
<h2>字典:{{ age_dist }}</h2>
<h3>字典中的元素:{{ age_dist['Alice'] }}</h3>
<hr>
{#控制代码块的使用#}
{% for name in name_list %}
{% if name == 'Alice' %}
<h2>{{ name }}的年龄是:{{ age_dist[name] }}</h2>
{% endif %}
{% endfor %}
<hr>
{#过滤器的使用#}
<h2>过滤器:{{ name_list[0]| upper }}</h2>
</body>
</html>

常用的一些内建过滤器

过滤器 操作
safe 禁用转义
capitalize 把变量值的首字母转成大写,其余字母转小写
lower 把值转成小写
upper 把值转成大写
title 把值中的每个单词的首字母都转成大写
reverse 字符串反转
format 格式化输出
striptags 渲染之前把值中所有的HTML标签都删掉
truncate 字符串截断
列表操作
first 取第一个元素
last 取最后一个元素
length 获取列表长度
sum 列表求和
sort 列表排序

也能根据自己需求自定过滤器,具体使用可以参考[这篇博客][https://www.cnblogs.com/skaarl/p/9397426.html]

表单验证

我们将实现一个用户注册的表单验证过程,用户获取表单页面需要get请求,而提交注册信息则需要使用post请求,这就涉及到同一路由处理两种请求,可以使用request

路由和视图函数的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
app.secret_key = 'abcd'
@app.route('/', methods=['POST', 'GET']) # 获取模板时需要get请求,上传文件需要POST请求
def index():
if request.method == 'POST': # 判断请求类型
username = request.form.get('username') # 获取表单信息
password = request.form.get('password')
password2 = request.form.get('password2')
if len(username) == 0 or len(password) == 0 or len(password2) == 0:
flash('参数不完整') # 使用flash闪现向模板传入消息
elif password != password2:
flash('密码不一致')
else:
return 'success'
return render_template('index.html')

html表单代码:

1
2
3
4
5
6
7
8
9
10
<form method="post">
<label>用户名</label><input type="text" name="username"><br>
<label>密码</label><input type="password" name="password"><br>
<label>确认密码</label><input type="password" name="password2"><br>
<input type="submit" value="提交" ><br>
{# 使用遍历获取闪现过来的消息#}
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
</form>

最后表单的效果,能够实现简易的表单验证(判断是否输入为空,两次密码输入是否相同)