一、flask上下文
上下文:即语境,语意,在程序中可以理解为在代码执行到某一时刻时,根据之前代码所做的操作以及下文即将要执行的逻辑,可以决定在当前时刻下可以使用到的变量,或者可以完成的事情。维持一段程序正常运行的所需要的外部变量的值的集合,叫做上下文(context)
Flask中有两种上下文:请求上下文和应用上下文
Flask中上下文对象:相当于一个容器,保存了 Flask 程序运行过程中的一些信息。
请求上下文
在 flask 中,可以直接在视图函数中使用 request 这个对象进行获取相关数据,而 request 就是请求上下文的对象,保存了当前本次请求的相关数据,请求上下文对象有:request、session
- request;封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get(‘user’),获取的是get请求的参数。
- session;用来记录请求会话中的信息,针对的是用户信息。举例:session[‘name’] = user.id,可以记录用户信息。还可以通过session.get(‘name’)获取用户信息。
在Flask中,request是一个全局变量,from flask import request,为了让不同的用户访问同一个视图,返回各自的数据,这里使用线程id区别不同的request。其原理如下图:
应用上下文
它的字面意思是 应用上下文,但它不是一直存在的,它只是request context 中的一个对 app 的代理(人),所谓local proxy。它的作用主要是帮助 request 获取当前的应用,它是伴 request 而生,随 request 而灭的。
类型是LocalProxy,像全局变量一样工作,但只能在处理请求期间且在处理它的线程中访问,返回的栈顶元素不是应用上下文,而是flask的应用实例对象。
应用上下文的封装 = flask核心对象+和外部协作对象(在flask封装对象上再添加push、pop等)(请求上下文同理)
应用上下文对象有:current_app(指定当前apph),g
g对象: g对象是一个空对象,一般会动态增加属性,来实现多个函数之间的传参
from flask import Flask, g
app = Flask(__name__)
@app.route("/")
def index():
# g保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过线程id区别
g.name = "zhangsan"
say_hello()
return "index page"
def say_hello():
name = g.name
print(f"Hello {name}")
if __name__ == '__main__':
app.run()
二 、请求钩子
在客户端和服务器之间记性交互的过程中,有些准备工作和扫尾工作需要处理,比如:在请求开始的时候,建立数据库连接,在请求结束的时候指定数据交互的格式,为了让每个视图函数避免编写重复的功能代码,Flask提供了通用设施的过程,即_请求钩子
请求钩子是通过装饰器的形式实现的,Flask支持四中请求钩子:
- app.before_first_request:在处理第一个请求前运行
- app.before_request:在每次请求之前运行
- app.after_request:如果没有未处理的异常抛出,在每次请求后运行(视图函数正常退出)
- app.teardown_request:每次请求后运行,即使有未处理的异常抛出
from flask import Flask, request, url_for, abort
app = Flask(__name__)
@app.route("/index")
def index():
print("index page is running")
a = 1 / 0
return "Index page"
@app.route("/hello")
def hello():
print("hello page is running")
return "Hello page"
@app.before_first_request
def handle_before_first_request():
# 在第一次请求处理之前先执行
print("handle_before_first_request is running")
@app.before_request
def handle_before_request():
# 在每次请求处理之前被执行
print("handle_before_request is running")
@app.after_request
def handle_after_request(response):
# 在每次请求(视图函数)处理之后都被执行,前提是视图函数没有异常
# 在请求之后,会接收一个参数,这个参数是前面的请求处理完毕后返回
# 的响应数据,如果需要对响应做额外处理,可以在这里进行
print(f"handle_after_request is running, the response is {response}")
return response
@app.teardown_request
def handle_teardown_request(response):
# 在每次请求(视图函数)处理之后都会被执行,无论视图函数是否异常
# 每一次请求之后都会调用,会接收一个参数,这个参数是服务器出现的
# 错误信息,工作在非调试模式下,当时图函数出现异常时,才会被执行
print(f"handle_teardown_request is running, the response is {response}")
if request.path == url_for("index"):
print("在请求钩子中判断请求的视图逻辑:index")
elif request.path == url_for("hello"):
print("在请求钩子中判断请求的视图逻辑:hello")
return response
if __name__ == '__main__':
app.run()
三 、flask_script脚本扩展的使用
先下载
pip install Flask-Script
from flask_script import Manager
使用:
- 1、创建Manager对象,把当前的flask应用传入Manager类中
manager = Manager(app) - 2、使用管理类来启动flask ;
manager.run()
在终端中使用:python 文件名.py --help 查看可用的命令:
- python 文件名.py runserver 启动服务器
- python 文件名.py runserver --help 查看可用命令
- python 文件名.py runserver -h IP地址 -p 端口号 指定ip端口号启动
- python 文件名.py shell 在这个shell终端中文件里的包已经全部导进来了,不需要在重新导入了
from flask import Flask
from flask_script import Manager
app = Flask(__name__)
manager = Manager(app)
@app.route("/index")
def index():
return "Index page"
if __name__ == '__main__':
manager.run()