Flask 学习笔记
Flask 项目中有两个上下文,一个是应用上下文(app),另外一个是请求上下文(request)。请求上下文 request 和 应用上下文 current_app 都是一个全局变量,所有请求都共享的。
Flask 有特殊的机制可以保证每次请求的数据都是隔离的,即 A 请求所产生的数据不会影响到 B 请求。所以可以直接导入 request 对象,也不会被一些脏数据影响了,并且不需要在每个函数中使用 request 的时候传入 request 对象。这两个上下文具体的实现方式。
request
:请求上下文上的对象。这个对象一般用来保存一些请求的变量,比如 method、args、form 等。
session
:请求上下文上的对象。这个对象一般用来保存一些会话信息。
current_app
:返回当前的 app。
app.config['SECRET_KEY'] = os.urandom(14)
@app.route("/login")
def login():
return "登录页面"
# 不能写在视图函数外面
# print(current_app.name)
@app.route("/")
def index():
# 获取当前文件名
print(current_app.name)
# 获取当前文件配置的一些属性
print(current_app.config['SECRET_KEY'])
return "这是首页"
g
:应用上下文上的对象。这个对象一般是处理请求时用作临时存储的对象。1.1、工具文件 utils.py
创建一个工具文件,进一步理解 “所有请求共享全局变量 current_app”。
def log_a(username):
print("log a %s" % username)
def log_b(username):
print("log b %s" % username)
from utils import log_a, log_b
@app.route("/")
def index():
username = session.get('username')
log_a(username)
log_b(username)
return "这是首页"
1.2、使用 g 对象实现
from flask import g
# 不需参数
def log_a():
print("log a %s" % g.username)
def log_b():
print("log b %s" % g.username)
@app.route("/")
def index():
username = session.get('username')
g.username = username
# 不需传参
log_a()
log_b()
return "这是首页"
2.1、before_first_request
# 处理第一次请求之前执行
@app.before_first_request
def first_request():
print '这是第一次请求之前执行的'
2.2、before_request
# 在每次请求之前执行. 通常可以用这个装饰器来给视图函数增加一些变量
@app.before_request
def handel_before():
if not hasattr(g,'user'):
setattr(g,'user','xxxx')
print("每次请求之前被执行的")
2.3、after_request
# 每次请求之后被执行的
# 这里注意, 需要传入参数(response 这个形参名字可以改)
# 因为是请求完成后执行, 自然就有响应返回
@app.after_request
def handel_after(response):
print("每次请求之后被执行的")
return response
2.4、teardown_appcontext
# 不管是否有异常, 注册的函数都会在每次请求之后执行
# 同理, 应传入参数(response 这个形参名字可以改)
@app.teardown_appcontext
def handel_teardowm(response):
print("handel_teardowm 被执行")
return response
2.5、context_processor
# 上下文处理器. 返回的字典中的键可以在模板上下文中使用
def index():
return render_template("index.html")
# 不使用 context_processor, 则需要在后面添加
# return render_template("index.html", username='check')
@app.route("/list")
def list():
return render_template("list.html")
# 每个还是都要添加
# return render_template("list.html", username='check')
# 当需要向多个 html 页面传输数据时, 使用该函数更方便
@app.context_processor
def context():
return {"username": "check"}
2.6、errorhandler
# errorhandler 接收状态码, 可以自定义返回这种状态码的响应的处理方法
@app.errorhandler(404)
def page_not_find(error):
# return render_template("404.html"), 404
return "页面不存在", 404
@app.errorhandler(500)
def server_error(error):
return "服务器内部错误...", 500
@app.route("/")
def index():
# 主动抛出404异常, 使得访问首页时显示 "页面不存在"
abort(404)
print("这是首页")
return render_template("index.html")