flask学习
一、什么是flask
Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。
Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团队在短时间内就可以完成功能丰富的中小型网站或Web服务的实现。另外,Flask还有很强的定制性,用户可以根据自己的需求来添加相应的功能,在保持核心功能简单的同时实现功能的丰富与扩展,其强大的插件库可以让用户实现个性化的网站定制,开发出功能强大的网站。
二、背景
看这个框架介绍感觉云里雾里的, 其实就是如果你不会写java但是还要将做一些应用开发,例如文件上传或者前端数据展示。这个框架不要求有太强的java开发基础,因为它是python语言编写的,这样的话对咱做数据的就很友好了,毕竟咱做数据湖那么久了python使用不能说如虎添翼,但这个框架确实让我们如鱼得水了。
三、Flask构成
-
路由(Routing):Flask 使用路由来定义 URL 和对应的处理函数。通过装饰器 @app.route(),可以将一个 URL 映射到相应的处理函数上,从而实现请求的路由和处理。
-
视图函数(View Functions):视图函数是 Flask 中处理请求的核心组件,它接收请求并返回响应。视图函数通常被装饰器绑定到特定的 URL 路由上。
-
请求上下文(Request Context):Flask 在处理请求时会创建一个请求上下文,其中包含了请求的信息,例如请求的方法、URL 参数、表单数据等。视图函数可以通过 request 对象来访问请求上下文中的数据。
-
响应对象(Response Object):视图函数需要返回一个响应对象,用于向客户端返回数据。Flask 提供了 make_response() 函数和 Response 类来构造响应对象,也可以直接返回字符串、模板渲染结果等。
-
模板引擎(Template Engine):Flask 默认使用 Jinja2 模板引擎来渲染 HTML 页面。模板引擎允许开发者在模板中嵌入动态内容,从而将数据和视图分离,使页面更加灵活和易于维护。
-
上下文全局变量(Context Globals):Flask 提供了一些上下文全局变量,例如 current_app 和 g,可以在视图函数中使用。current_app 表示当前应用的实例,g 是一个全局变量字典,可以在同一请求中共享数据。
-
扩展(Extensions):Flask 的功能可以通过扩展来增强,例如数据库支持、表单验证、用户认证等。Flask 社区提供了大量的扩展,使开发者能够更方便地添加功能。
-
蓝图(Blueprint):蓝图是一种将 Flask 应用分割为小模块的方式,可以将相关的路由和视图函数组织在一个蓝图中,使应用更加结构化和易于管理。
四、运用
4.1、helloworld
from flask import Flask, request, jsonify, render_template, redirect
# 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
app = Flask(__name__)
# 在Flask中,通过@app.route装饰器来表示路由
@app.route("/")
def index():
return "Hello World!"
# 启动http服务
if __name__ == '__main__':
# 默认端口5000
app.run(debug=True)
# app.run(debug=True,port=6666) 自定义端口为6666
在浏览器输入
http://127.0.0.1:5000
可以看到helloworld
4.2、请求方式
methods用于指定允许的请求方式,默认是get请求
from flask import Flask, request, jsonify, render_template, redirect
app = Flask(__name__)
@app.route("/hello", methods=['GET', 'POST'])
def hello():
return "Hello Mr,Tree!"
# 启动http服务
if __name__ == '__main__':
app.run(debug=True)
请求方式 | 说明 | 底层 |
---|---|---|
GET | 从指定的资源请求数据 | 浏览器会把 http header 和 data 一并发送出去,服务器响应 200 (返回数据)表示成功 |
POST | 向指定的资源提交要被处理的数据。 | 浏览器先发送 header,服务器响应 100, 浏览器再继续发送 data,服务器响应 200 (返回数据) |
from flask import Flask, request, jsonify, render_template, redirect
app = Flask(__name__)
# 默认请求方式为 GET
@app.route("/index/request")
def index_request():
if request.method == 'GET':
return 'GET'
elif request.method == 'POST':
return 'POST'
# 启动http服务
if __name__ == '__main__':
app.run(debug=True)
访问
http://127.0.0.1:5000/index/request
显示
GET
4.3、参数
4.3.1、在roote中指定多个参数
from flask import Flask, request, jsonify, render_template, redirect
app = Flask(__name__)
# 指定固定格式的参数类型(此处制定了两个参数)
@app.route("/index/<int:id>/<name>", methods=['GET', 'POST'])
def index(id, name):
return f'{id} = {name}'
# 启动http服务
if __name__ == '__main__':
app.run(debug=True)
参数 | 说明 |
---|---|
string | 字符串类型,可以是任意字符 |
int | 整数类型 |
float | 浮点数类型 |
path | 类似于字符串类型,但可以包含斜杠(/) |
uuid | UUID(通用唯一标识符)类型 |
访问
http://127.0.0.1:5000/index/1/king
网页显示
1 = king
4.3.2、传入参数为路径
from flask import Flask, request, jsonify, render_template, redirect
app = Flask(__name__)
# 指定固定格式的参数类型(此处制定了两个参数)
@app.route('/index/files', methods=['GET'])
def get_parameter():
path = request.args.get('path')
# 使用path进行相关操作
return 'Path: {}'.format(path)
# 启动http服务
if __name__ == '__main__':
app.run(debug=True)
访问
http://127.0.0.1:5000/index/files?path=/tmp/load
网页显示
Path: /tmp/load
4.3.3、传入参数为数组
from flask import Flask, request, jsonify, render_template, redirect
app = Flask(__name__)
@app.route('/index/names', methods=['GET'])
def get_parameter():
names = request.args.getlist('names')
return f'Names: {names}'
# 启动http服务
if __name__ == '__main__':
app.run(debug=True)
访问
http://127.0.0.1:5000/index/names?names=a&names=b
网页显示
Names: [‘a’, ‘b’]
4.4.4、返回 json 给前端
from flask import Flask, jsonify
app = Flask(__name__)
# 返回json数据给前端
@app.route("/index/json")
def index():
data = {
'name': 'Tree'
}
return jsonify(data)
# 启动http服务
if __name__ == '__main__':
app.run()
访问
http://localhost:5000/index/json
显示
{
"name": "Tree"
}
4.4.5、动态url构建
动态选择,根据url传入参数的不同,动态跳转到不通的url
from flask import Flask, request, jsonify, render_template, redirect
app = Flask(__name__)
@app.route('/a')
def get_a():
return 'Hello a'
@app.route('/other/<string:name>')
def get_other(name):
return f'Hello {name}'
@app.route('/index/<name>')
def get_parameter(name):
# 当传入参数为a时自动跳转连接到 http://127.0.0.1:5000/a
if name == 'a':
return redirect(url_for('get_a'))
else:
return redirect(url_for('get_other', name=name))es}'
# 启动http服务
if __name__ == '__main__':
app.run(debug=True)
访问
http://127.0.0.1:5000/index/a
url自动跳转到
http://127.0.0.1:5000/a
访问
http://127.0.0.1:5000/index/b
url自动跳转到
http://127.0.0.1:5000/other/b
4.4、模板
python代码生成html会较为复杂,但是可以通过render_template()函数渲染HTML文件。
render_template(‘html名称’),这样会在python模块的同级目录下寻找templetes文件夹内中的html名称对应的文件进行渲染。
现有目录如下:
– test.py
– remplates
| – 基金收盘价.html
from flask import Flask, request, jsonify, render_template, redirect
app = Flask(__name__)
@app.route('/index')
def get_template():
return render_template('基金收盘价.html')
# 启动http服务
if __name__ == '__main__':
app.run(debug=True)
访问
http://127.0.0.1:5000/index
显示
基金收盘价.html 页面
4.5、钩子函数
有时候我们需要在正常访问的前后固定执行某些操作,这个就用到了钩子函数,只需要为需要执行的方法添加装饰器即可
from flask import Flask, request, jsonify, render_template, redirect
app = Flask(__name__)
# 发起请求之前执行此方法
@app.before_request
def before_request_a():
print('before_request_a')
# 请求结束以后执行此方法
@app.after_request
def after_request_a(response):
print('after_request_a')
# 装饰器接收response参数,运行完必须归还response,否则程序报错
return response)
@app.route("/hello", methods=['GET', 'POST'])
def hello():
return "Hello Mr,Tree!"
# 启动http服务
if __name__ == '__main__':
app.run(debug=True)
参数 | 运行时 | 说明 |
---|---|---|
before_first_request | 请求之前 | 仅第一次请求前会被调用 |
before_request | 请求之前 | 每一次请求前都会被调用 |
after_request | 请求之后 | 每一次请求之后都会调用(没有未处理异常的情况) |
teardown_request | 请求之后 | 每一次请求之后都会调用(有无异常都可以,debug模式关闭) |
4.6、文件上传
1、创建一个enctype属性设置为’multipart/form-data’的HTML表单,并提交到指定的URL
2、 URL处理程序从request.files[]对象中提取文件并将其保存到所需的位置,每个文件上传会先传输到临时位置,上传完毕后保存到目标位置。
文件上传的临时目录默认是由 Werkzeug(Flask 底层使用的 WSGI 工具集)和底层操作系统控制的。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Flask示例</title>
</head>
<body>
<form action = "http://localhost:5000/index/upload" method = "POST"
enctype = "multipart/form-data">
<input type = "file" name = "file" />
<input type = "submit" value="提交"/>
</form>
</body>
</html>
import os
from flask import Flask, request, render_template
app = Flask(__name__)
# 指定文件上传的路径
app.config['UPLOAD_FOLDER'] = './uploads'
@app.route('/index/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
print(request.files)
file_path = os.path.join(app.config['UPLOAD_FOLDER'], f.filename)
f.save(file_path)
return 'file uploaded successfully'
else:
return render_template('upload.html')
# 启动http服务
if __name__ == '__main__':
app.run()
4.7、邮件发送
需要先安装邮件发送的第三方包
pip install Flask-Mail
案例
from flask import Flask
from flask_mail import Mail, Message
app =Flask(__name__)
mail=Mail(app)
app.config['MAIL_SERVER']='邮件服务器的名称/IP地址'
app.config['MAIL_PORT'] = 所用服务器的端口号
app.config['MAIL_USERNAME'] = '发件人的用户名'
app.config['MAIL_PASSWORD'] = '发件人的用户密码'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = Mail(app)
@app.route("/index/mail")
def index():
msg = Message('邮件文本', sender='邮件发送人的邮箱', recipients=['收件人邮箱'])
msg.body = "Hello Flask message sent from Flask-Mail"
mail.send(msg)
return "Sent"
if __name__ == '__main__':
app.run(debug=True)
4.7.1、邮件发送配置参数说明
参数 | 说明 |
---|---|
MAIL_SERVER | 邮件服务器的名称/IP地址 |
MAIL_PORT | 所用服务器的端口号 |
MAIL_USE_TLS | 启用/禁用传输安全层加密 |
MAIL_USE_SSL | 启用/禁用安全接字层加密 |
MAIL_DEBUG | 调试支持,默认是Flask应用程序的调试状态 |
MAIL_USERNAME | 发件人的用户名 |
MAIL_PASSWORD | 发件人的密码 |
MAIL_DEFAULT_SENDER | 设置默认发件人 |
MAIL_MAX_EMAILS | 设置要发送的最大邮件 |
MAIL_SUPPRESS_SEND | 如果app.testing设置为true,则发送被抑制 |
MAIL_ASCII_ATTACHMENTS | 如果设置为true,则将附加的文件名转换为ASCII |
4.7.2、Mail方法说明
方法 | 说明 |
---|---|
send() | 发送Message类对象的内容 |
connect() | 与邮件主机打开连接 |
send_message() | 发送消息对象 |
4.7.3、Message类方法说明
方法 | 参数 | 说明 |
---|---|---|
attach() | 向消息添加附件 | |
filename | 要附加的文件的名称 | |
content_type | 文件的MIME类型 | |
data | 原始文件数据 | |
disposition | 内容处置 | |
add_recipient() | 向消息添加另一个收件人(抄送) |
|
| send_message() | 发送消息对象 |
4.7.3、Message类方法说明
方法 | 参数 | 说明 |
---|---|---|
attach() | 向消息添加附件 | |
filename | 要附加的文件的名称 | |
content_type | 文件的MIME类型 | |
data | 原始文件数据 | |
disposition | 内容处置 | |
add_recipient() | 向消息添加另一个收件人(抄送) |