闪现、请求扩展、g对象
目录
一 闪现
要求
# 一个请求--->假设出错了--->重定向到另一个地址--->把错误信息在另一个返回中看到
错误信息放个位置---->另一个请求过来,去那个位置拿
或者将错误信息直接拼接到路径后面,直接去GET参数中获取。(这样的坏处:别人会看到错误的信息)
def index():
s='xx错位了'
return redirect('/errors')
def errors():
return index.html
闪现
# 闪现:把一些数据,放在某个位置--->后期可以去取出来---->取完不用手动删除,会自己删除的
# 如何设置
flash('aaa')
# 如何取
get_flashed_message()
示例
from flask import Flask,flash,get_flashed_messages
app=Flask(__name__)
app.debug=True
app.secret_key='asdfasdfasdfa'
# 只要用闪现--->就要设置secret_key---->闪现是把数据放到session中了
@app.route('/')
def index():
# 放入我的名字
flash('lqz') # 放哪了?session中
return 'xxx'
@app.route('/home')
def home():
# 取出我的名字
name=get_flashed_messages()
print(name)
return 'home'
@app.route('/order')
def order():
# 先执行了home后,这个就取出空列表
name=get_flashed_messages()
print(name)
return 'order'
if __name__ == '__main__':
app.run()
分类放
# 分类放
flash('超时错误', category="x1")
# 分类取
data = get_flashed_messages(category_filter=['x1'])
from flask import Flask,flash,get_flashed_messages
app=Flask(__name__)
app.debug=True
app.secret_key='asdfasdfasdfa'
# 只要用闪现--->就要设置secret_key---->放到session中了
@app.route('/')
def index():
# 分类放
flash('超时错误', category="x1")
return 'xxx'
@app.route('/home')
def home():
# 按照分类取值
# name=get_flashed_messages() # 不写分类,会全部取出
name=get_flashed_messages(category_filter=['x2'])
print(name)
return 'home'
@app.route('/order')
def order():
data = get_flashed_messages(category_filter=['x1'])
print(data)
# 按分类取
return 'order'
if __name__ == '__main__':
app.run()
# 1 django 的message框架就是做这个事的
# 2 闪现有什么用?
-暂时存数据
-当次请求出错了,下次请求要显示这个错误
二 请求扩展
# 类似于django中的中间件
-请求来了,请求走了,做一些拦截
1 before_request
2 after_request
3 before_first_request
4 teardown_request
5 errorhandler
6 template_global
7 template_filter
before_request
# 请求来了执行--->django中的process_request--->可以下多个,从上往下依次执行
# 1 判断访问的不同路径
from flask import Flask, request, render_template, jsonify
@app.before_request
def before():
# 当次请求的对象就是全局的request
if request.path=='/':
print('我来了')
else:
print('访问其他路径')
@app.route('/')
def index():
return 'xxx'
@app.route('/home')
def home():
return 'home'
# 2 往requuest对象中加值。判断如果是跟路径,向request对象中放个name,其他不放
@app.before_request
def before():
if request.path == '/':
request.name = 'lqz'
else:
print('访问其他路径')
@app.route('/')
def index():
print(request.name) # 'lqz'
return 'xxx'
@app.route('/home')
def home():
print(request.name) # 没有,会报错
return 'home'
# 3 返回None,会执行下一个请求扩展,如果返回4件套,直接就返回了,不再往下执行了
@app.before_request
def before():
if request.path=='/':
return '不让你访问'
else:
print('访问其他路径')
# 4 多个before_request,从上往下执行
@app.before_request
def before():
print('1111')
return 'xxxxxx' # 这里写了return 就直接返回,不会走第二个before_request
@app.before_request
def before2():
print('2222')
@app.route('/')
def index():
return 'xxx'
after_request
from flask import Flask
app = Flask(__name__)
@app.after_request #--->类似于django中的process_response
def after(response):
print(response) # 正常响应对象
print('走了走了')
return response # 一定要返回response对象
@app.route('/')
def index():
return 'xxx'
# 1 处理跨域
@app.after_request
def after(response):
print(response)
print('走了走了')
# 在响应头中加值
response.headers['xxx']='eeeee'
return response # 一定要返回response对象
@app.route('/')
def index():
return 'xxx'
# 2 多个before_request和 after_request执行顺序----> 请求来了从上往下执行before_request,请求走了,从下往上执行
from flask import Flask
app = Flask(__name__)
@app.before_request
def before():
print('1111')
@app.before_request
def before2():
print('2222')
@app.after_request
def after(response):
print('走了走了')
return response # 一定要返回response对象
@app.after_request
def after2(response):
print('走了走了222')
return response
@app.route('/')
def index():
print('函数执行')
return 'xxx'
if __name__ == '__main__':
app.run()
'''
1111
2222
函数执行
走了走了222
走了走了
'''
before_first_request
# 项目运行起来的第一次会执行,以后再也不执行了
# 1.x可以,2.x弃用了
teardown_request
# teardown_request 每一个请求之后绑定一个函数,即使遇到了异常--->一般用来记录日志--->不能做统一异常处理
@app.teardown_request
def ttt(e):
# 通过判断e是否为空,记录日志
print(e) # 出了异常,e就是异常对象,如果没有异常,e就是None
print('来了老弟')
# if e: # 这里写了return 也不会执行,会报错的
# return '出异常了'
@app.route('/')
def index():
return 'xxx'
errorhandler
## errorhandler,可以做统一的异常处理
from flask import Flask, request, render_template, jsonify
app = Flask(__name__)
# 参数写HTTP的响应状态码,路径不存在时404,服务器内部错误500
@app.errorhandler(404) # error=errorhandler(404)(error)
def error(e):
print(e)
print('xxx')
return render_template('error.html')
@app.errorhandler(500) # 这里要设置debug=false,设置成上线模式
def error1(e):
print(e)
print('500')
return jsonify({'code': 999, 'msg': '服务器内部错误,请联系系统管理员'})
@app.route('/')
def index():
a = [1, 2, 3]
print(a[9])
return render_template('index.html')
template_global全局标签
# template_global 全局标签,所有页面都可以用 ---> django中dtl的标签和过滤器
@app.template_global()
def add(a1, a2):
return a1 + a2
# index.html
<body>
<!--执行函数,页面上显示函数return的值-->
{{add(4, 5)}}
</body>
template_filter全局过滤器
# template_filter 全局过滤器
@app.template_filter()
def db(a1, a2, a3):
print(a1)
return a1 + a2 + a3
# index.html
<body>
<!--执行函数,页面上显示函数return的值-->
{{4|db(5, 6)}}
</body>
三 g对象
# 请求来了,在request中放个path,后续的视图函数中都能拿到
# flask不建议向request对象中放变量,会污染原来的request中的变量,建议使用g对象
# g对象,当次请求中放入的变量,在当次请求中一直存在
# global的缩写,global
# g和session的区别
-g只针对于当次请求
-session可以跨请求
from flask import Flask, request, g
app = Flask(__name__)
# 1 直接使用
from flask import Flask, request, g
app = Flask(__name__)
@app.before_request
def before():
if request.path == '/':
g.path = 'lqz'
@app.route('/')
def index():
print(g.path) # lqz
return 'index'
if __name__ == '__main__':
app.run()
# 2 可以使用函数,函数中调用g.path。在当此请求下都有效
@app.before_request
def before():
if request.path == '/':
# 存g.path
g.path = 'lqz'
def test():
print("test", g.path)
@app.route('/')
def index():
test()
return 'index'
@app.route('/home')
def home():
print(g.path) # 这次的路径中,就没有放入g.path,所以就取不到值的
return 'home'
# 函数中就不需要传值了,在当此请求中,只要提前赋值,就可以直接使用了
@app.before_request
def before():
if request.path == '/':
g.path = 'lqz'
def add():
return g.a + g.b
@app.route('/')
def index():
g.a = 10
g.b = 100
add()
print(g.a) # 函数执行结束后,后面还可以继续使用
return 'index'
if __name__ == '__main__':
app.run()
四 蓝图
# blueprint :蓝图,flask都写在一个文件中,项目这样肯定不行,分目录,分包,使用蓝图划分目录
# 不用蓝图,划分目录
-一直使用app对象,会出现循环导入问题
-项目名
static
templates
order_detail.html
views
__init__.py
goods.py
order.py
user.py
manage.py
-代码看详情
# 使用蓝图:所有步骤
-1 实例化得到一个蓝图对象
-order_blue=Blueprint('order',__name__,template_folder='../templates')
-2 以后注册路由,写请求扩展,都使用蓝图
@user_blue.before_request
@user_blue.route('/register')
-3 在app中注册蓝图
from . import user
app.register_blueprint(user.user_blue)
app.register_blueprint(user.user_blue,url_prefix='/user')
4.1 使用蓝图
4.2 蓝图小型项目
flask_blueprint_little # 项目名
src # 核心文件
__init__.py #包的inin里面实例化得到app对象
views # 视图函数,类
user.py
order.py
templates #模板
user.html
static #静态文件
manage.py #启动文件
4.3 蓝图大型项目
五 flask-session
# flask 自带session--->以cookie的形式放到了浏览器中--->加密
#真正的session,是在服务端存储
-django中存在djangosession表中
-flask中,使用第三方,保存在--->redis中--->flask-session
#flask能不能用jwt
# 使用步骤
pip3 install flask-session
# 降一下flask版本即可
# 用高版本:在app中放一个参数 app.session_cookie_name='session'
# 使用方式一:
from flask_session import RedisSessionInterface
app.session_cookie_name='session'
app.session_interface=RedisSessionInterface(redis=None,key_prefix='lqz') # 动态替换,把原来的session对象换成放到redis的session对象
# 4 以后再使用session,就会存到redis中了
session.get()
session[]=value赋值
# 使用方式二:
from redis import Redis
from flask_session import Session
app.session_cookie_name = 'session'
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis(host='127.0.0.1',port='6379')
Session(app)
,