@[TOC]
一、安装
1、下载
pip install flask
2、基本使用
from flask import Flask
# 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
app = Flask(__name__)
# @app.route() 指定路由 ,methods指定方法
@app.route("/", methods=['GET'])
def index():
return "Hello World!"
# 支持post请求
@app.route("/hi",methods=['POST'])
def hi():
return "Hi World!"
# 启动一个本地开发服务器,激活该网页
app.run()
3、运行
# 1、直接执行py程序
py test,py
# 2、使用flask命令
flask --app test run
# debug模式
flask --app test run --debug
# 外部可访问
flask --app test run --host=0.0.0.0
二、基本语法
1、参数接收
(1)路径参数
from flask import Flask
app = Flask(__name__)
# 可以在路径内以/<参数名>的形式指定参数,默认接收到的参数类型是string
'''#######################
以下为框架自带的转换器,可以置于参数前将接收的参数转化为对应类型
string 接受任何不包含斜杠的文本
int 接受正整数
float 接受正浮点数
path 接受包含斜杠的文本
########################'''
# 访问http://localhost:5000/index/1 ;1就是id参数
@app.route("/index/<int:id>",)
def index(id):
if id == 1:
return 'first'
elif id == 2:
return 'second'
elif id == 3:
return 'thrid'
else:
return 'hello world!'
if __name__=='__main__':
app.run()
除了原有的转换器,我们也可以自定义转换器(pip install werkzeug):此处略了。
(2)form参数
接收post请求的form参数
# 判断请求方式
if request.method == 'POST':
# 获取表单中name为username的文本域提交的数据
name = request.form.get('username')
# 获取表单中name为password的文本域提交的数据
password = request.form.get('password')
return name+" "+password
(3)Json处理
from flask import Flask
from flask import jsonify
from flask import request
app = Flask(__name__)
# 在Flask的config是一个存储了各项配置的字典
# 该操作是进行等效于ensure_ascii=False的配置
app.config['JSON_AS_ASCII'] = False
@app.route("/login", methods=['POST'])
def login():
if request.method == 'POST':
# 接收json数据,这个data就是json对象了
data = request.get_json()
username = data['username']
password = data['password']
print(username)
print(password)
# 将对象返回为json
return jsonify({"login": "success"})
if __name__=='__main__':
app.run()
(4)get请求参数
from flask import Flask, request
app = Flask(__name__)
@app.route('/hello')
def hello():
name = request.args.get('name')
age = request.args.get('age')
return f"Hello {name}, you are {age} years old!"
if __name__ == '__main__':
app.run()
2、GET、POST请求
from flask import request
# 可以用methods指定,也可以直接使用@app.get
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return do_the_login()
else:
return show_the_login_form()
@app.get('/login')
def login_get():
return show_the_login_form()
@app.post('/login')
def login_post():
return do_the_login()
3、拦截器
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
# before_request:在每一次请求之前调用 先绑定的先执行
@app.before_request
def before_request_a():
print('I am in before_request_a')
@app.before_request
def before_request_b():
print('I am in before_request_b')
# before_first_request:与before_request的区别是,只在第一次请求之前调用
@app.before_first_request
def teardown_request_a():
print('I am in teardown_request_a')
@app.before_first_request
def teardown_request_b():
print('I am in teardown_request_b')
# after_request:每一次请求之后都会调用 先绑定的后执行
@app.after_request
def after_request_a(response):
print('I am in after_request_a')
# 该装饰器接收response参数,运行完必须归还response,不然程序报错
return response
@app.after_request
def after_request_b(response):
print('I am in after_request_b')
return response
# teardown_request:每一次请求之后都会调用 先绑定的后执行
# 代码替换视图函数hello_world后,if main前
@app.teardown_request
def teardown_request_a(exc):
print('I am in teardown_request_a')
@app.teardown_request
def teardown_request_b(exc):
print('I am in teardown_request_b')
if __name__ == '__main__':
app.run()
4、上传文件
import os
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename
# 上传路径
#UPLOAD_FOLDER = '/path/to/the/
UPLOAD_FOLDER = 'E:\\testdir'
# 允许上传的文件类型
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
# 文件上传路径
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# 限制文件上传大小16 M
app.config['MAX_CONTENT_LENGTH'] = 16 * 1000 * 1000
# 判断文件格式是否允许上传
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
# 文件保存到本地,上传完重定向的文件
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('download_file', name=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''
from flask import send_from_directory
@app.route('/uploads/<name>')
def download_file(name):
return send_from_directory(app.config["UPLOAD_FOLDER"], name)
# 如果您正在使用中间件或者 HTTP 服务器为文件提供服务,那么可以把 download_file 端点注册为 build_only 规则,这样 url_for 会在 没有视图函数的情况下生效。
app.add_url_rule(
"/uploads/<name>", endpoint="download_file", build_only=True
)
app.run()
5、使用html模板
Jinja2 模板引擎,可以参考:https://jinja.palletsprojects.com/en/3.1.x/templates/
from flask import render_template
from flask import Flask
app = Flask(__name__)
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
app.run()
模板文件需要在templates目录下。
<!doctype html>
<title>Hello from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
三、高级用法
1、蓝图
引入蓝图(flask.Blueprint),用于实现程序功能的模块化
当接收到请求时,Flask会遍历Flask对象下(已注册)的各蓝图对象,比对蓝图对象中记录的url,比对成功则映射到该url绑定的视图函数并返回响应
# 模块一
from flask import Blueprint
# 实例化蓝图对象,参数一类似于蓝图对象的名称
# 一个app下的蓝图对象不可重名 可以指定前缀
product_list = Blueprint('products',__name__,url_prefix='/products')
# 蓝图对象的使用和app类似
# 一个蓝图下的视图函数名、endpoint不可重复
# http://localhost:5000/products/list
@product_list.route('/list')
def products():
return '这是产品模块!'
# 模块二
from flask import Blueprint
# 实例化蓝图对象,参数一类似于蓝图对象的名称
# 一个app下的蓝图对象不可重名 可以指定前缀
new_list = Blueprint('news',__name__,url_prefix='/news')
# 蓝图对象的使用和app类似
# 一个蓝图下的视图函数名、endpoint不可重复
# http://localhost:5000/news/list
@new_list.route('/list')
def news():
return '这是新闻模块!'
# 主方法
from flask import Flask
from sub import products,news
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'hello my world !'
# 将对应模块下的蓝图对象注册到app中
app.register_blueprint(news.new_list)
app.register_blueprint(products.product_list)
if __name__ == '__main__':
app.run(debug=True)
2、使用Gunicorn部署
注意,Gunicorn不支持windows,会报错No module named 'fcntl'
# 安装Gunicorn
pip install gunicorn
# -w 指定线程数 -b绑定的ip
gunicorn -w 4 -b 0.0.0.0 hello:create_app()
参考资料
https://blog.csdn.net/wly55690/article/details/131683846
官方文档:
https://www.osgeo.cn/flask/
https://dormousehole.readthedocs.io/en/latest/
【重磅推荐!免费简单内网穿透神器!支持linux+windows】
推荐内网穿透神器【cpolar】www.cpolar.com/ 点击【免费注册】之后,输入自己的个人信息就可以注册一个账号啦! 本地web项目如何使用外网访问?教你轻松使用cpolar在windows搭建内网穿透 linux虚拟机部署的web项目如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透 linux虚拟机部署的MySQL如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透