Flask--闪现、中间件、多app应用
闪现
flask提供了一个非常有用的flash()函数,它可以用来“闪现”需要提示给用户的消息,比如当用户登录成功后显示“欢迎回来!”。在视图函数调用flash()函数,传入消息内容,flash()
函数把消息存储在session中,我们需要在模板中使用全局函数get_flashed_messages()
获取消息并将它显示出来。
通过flash()
函数发送的消息会存储在session对象中,所以我们需要为程序设置秘钥。可以通过app.secret_key属性或配置变量SECRET_KEY设置。
源码
def flash(message, category="message"): # 默认category为message
flashes = session.get("_flashes", [])
flashes.append((category, message))
session["_flashes"] = flashes
message_flashed.send(
current_app._get_current_object(), message=message, category=category
)
def get_flashed_messages(with_categories=False, category_filter=()):
flashes = _request_ctx_stack.top.flashes
if flashes is None:
_request_ctx_stack.top.flashes = flashes = (
session.pop("_flashes") if "_flashes" in session else []
)
if category_filter:
flashes = list(filter(lambda f: f[0] in category_filter, flashes))
if not with_categories:
return [x[1] for x in flashes]
return flashes
-
设置flash
flash("要传递的值",category="分类的名称")
,如果不传默认是message- 本质:
session['_flash']
-
取flash设置的值我们用
get_flashed_messages
get_flashed_messages(with_categories=False, category_filter=())
- 如果不传递
category_filter
,取出上面存储的所有分类传递的值 - 如果不传with_categories就只取值,不取分类的名字,如果传值,就获取 分类名和分类值
- 如果不传递
-
这个flash只能一个视图函数中取,只要有一个视图函数取过了,那其他视图函数就不能获取
- 本质:
session.pop("_flash")
- 但是在同一个视图函数里面可以无限的取值
- 本质:
案例
from flask import Flask,flash,get_flashed_messages,request,redirect
app = Flask(__name__)
app.debug=True
app.secret_key = 'asdfasdf'
@app.route('/index')
def index():
# 从某个地方获取设置过的所有值,并清除。
#flash('超时错误',category="x1")
flash("它过来了,你要小心")
flash("我是第二个",category="ss")
# return "ssdsdsdfsd"
return redirect('/error')
@app.route('/error')
def error():
"""
展示错误信息
:return:
如果get_flashed_messages(with_category=True)
"""
#data = get_flashed_messages(category_filter=['x1'])
data=get_flashed_messages(with_categories=True,category_filter=['ss'])
data1 = get_flashed_messages(with_categories=True, category_filter=['ss'])
print(type(data))
print(data1)
return "错误信息:%s" %(data,)
if __name__ == '__main__':
app.run()
中间件
本质就是把原来的执行函数又做了一层封装
注意:Flask的请求扩展就是Django的中间件。Django的中间件不是Flask的中间件
自定义局部中间件
根据装饰器
from functools import wraps
def auth(func):
@wraps(func)
def inner(*args, **kwargs):
if not session.get('user'):
return redirect(url_for('login'))
ret = func(*args, **kwargs)
return ret
return inner
@app.route('/login', methods=["GET", "POST"])
@auth
def login():
return "登录"
自定义全局装饰器
写在app.py中
class Middleware(object):
def __init__(self, old):
self.old = old
def __call__(self, *args, **kwargs):
print('请求前的操作')
ret = self.old(*args, **kwargs)
print('请求之后操作')
return ret
if __name__ == '__main__':
app.wsgi_app = Middleware(app.wsgi_app)
app.run()
多app应用
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
from flask import Flask, current_app
app1 = Flask('app01')
app2 = Flask('app02')
@app1.route('/index')
def index():
return "app01"
@app2.route('/index2')
def index2():
return "app2"
# http://www.oldboyedu.com/index
# http://www.oldboyedu.com/sec/index2
dm = DispatcherMiddleware(app1, {
'/sec': app2,
})
if __name__ == "__main__":
run_simple('localhost', 5000, dm)