flask_上下文处理_flask脚手架
context
什么是上下文
日常生活中的上下文:
从一篇文章中抽取一段话,你阅读后,可能依旧无法理解这段话中想表达的内容,因为它引用了文章其他部分的观点,要理解这段话,需要先阅读理解这些观点。 这些散落于文章的观点就是这段话的上下文。
对Flask框架来说就是:
Flask从客户端收到请求的时候,视图函数如果要处理请求的话,可能需要访问/使用一些对象。那么这些对象可以通过参数的形式传递进来,或者在函数中通过访问外部变量来用。
这个外部变量要有特定的值才会有意义,那么这些有特定值或者特定意义的外部变量的集合就是上下文
例子:
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def index():
user_agent = request.headers.get('User-Agent')
return 'Your brower is %s' % user_agent
if __name__ == '__main__':
app.run()
这里的request变量就是请求上下文,也就是当请求被推送之后,request才有意义,接下来才可以用request。
Flask 上下文作用
例如:Flask 的视图函数被使用的时候是需要知道前端请求的 url、请求参数等应用信息才可以正常运行,那么要怎么设计实现呢?
Flask 为此设计出了自己的上下文机制,当在特定场景下需要使用请求信息时,直接 from flask import request就可以获得当前请求的所有信息并且在多线程环境下是线程安全的。
总结
Flask中上下文对象:相当于一个容器,保存了 Flask 程序运行过程中的一些信息[变量、函数、类与对象等信息]。
Flask中有两种上下文,请求上下文(request context)和应用上下文(application context)。
请求上下文(request context)
请求上下文提供的变量/属性/方法/函数/类与对象,只能在视图中或者被视图调用的地方使用。
思考:在视图函数中,如何取到当前请求的相关数据?比如:请求地址,请求方式,cookie等等
在 flask 中,可以直接在视图函数中使用 request 这个对象进行获取相关数据,而 request 就是请求上下文的对象,保存了当前本次请求的相关数据,请求上下文对象有:request、session
- request
- 封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get('user'),获取的是get请求的参数。
- session
- 用来记录请求会话中的信息,针对的是用户信息。举例:session['name'] = user.id,可以记录用户信息。还可以通过session.get('name')获取用户信息。
请求上下文提供的变量/属性/方法/函数/类与对象,只能在视图中或者被视图调用的地方使用
应用上下文(application context)
应用上下文它不是一直存在的,它只是请求上下文中的一个对app的代理,所谓的local proxy。它的作用主要是帮助request获取当前的应用,它是伴request而生,随request而灭的。
应用上下文提供给我们使用的变量,也是只能在视图或者被视图调用的地方进行使用
应用上下文对象有:current_app,g
current_app
应用程序上下文,用于存储应用程序中的变量,可以通过current_app.name打印当前app的名称,也可以在current_app中存储一些变量,例如:
- 应用的启动脚本是哪个文件,启动时指定了哪些参数
- 加载了哪些配置文件,导入了哪些配置
- 连接了哪个数据库
- 有哪些可以调用的工具类、常量
- 当前flask应用在哪个机器上,哪个IP上运行,内存多大
from flask import Flask,request,session,current_app,g
# 初始化
app = Flask(import_name=__name__)
# 声明和加载配置
class Config():
DEBUG = True
app.config.from_object(Config)
# 编写路由视图
@app.route(rule='/')
def index():
# 应用上下文提供给我们使用的变量,也是只能在视图或者被视图调用的地方进行使用,
# 但是应用上下文的所有数据来源于于app,每个视图中的应用上下文基本一样
print(current_app.config) # 获取当前项目的所有配置信息
print(current_app.url_map) # 获取当前项目的所有路由信息
return "<h1>hello world!</h1>"
if __name__ == '__main__':
# 运行flask
app.run(host="0.0.0.0")
g变量
g 作为 flask 程序全局的一个临时变量,充当者中间媒介的作用,我们可以通过它传递一些数据,g 保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过不同的thread id区别
g.name='abc' # name是举例,实际要保存什么数据到g变量中,可以根据业务而定,你可以任意的数据进去
注意:不同的请求,会有不同的全局变量g
from flask import Flask,request,session,current_app,g
# 初始化
app = Flask(import_name=__name__)
# 声明和加载配置
class Config():
DEBUG = True
app.config.from_object(Config)
@app.before_request
def before_request():
g.name = "root"
def get_func():
name = g.name
print("g.name=%s" % name)
# 编写路由视图
@app.route(rule='/')
def index():
get_func()
return "<h1>hello world!</h1>"
if __name__ == '__main__':
# 运行flask
app.run(host="0.0.0.0")
两者区别:
- 请求上下文:保存了客户端和服务器交互的数据,一般来自于客户端。
- 应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如路由列表,程序名、数据库连接、应用信息等
Flask-Script 扩展(终端脚本工具)
这个模块的作用可以让我们通过终端来控制flask项目的运行,类似于django的manage.py
安装命令:
pip install flask-script
集成 flask-script到flask应用中,创建一个主应用程序,一般我们叫manage.py/run.py/main.py都行。
from flask import Flask
app = Flask(__name__)
"""使用flask_script启动项目"""
from flask_script import Manager
manage = Manager(app)
@app.route('/')
def index():
return 'hello world'
if __name__ == "__main__":
manager.run()
启动终端脚本运行项目的命令:
# 端口和域名不写,默认为127.0.0.1:5000
python run.py runserver
# 通过-h设置启动域名,-p设置启动端口
python run.py runserver -h127.0.0.1 -p8888
Flask-Script 还可以为当前应用程序添加脚本命令
1. 引入Command命令基类
2. 创建命令类必须直接或间接继承Command,并在内部实现run方法,同时如果有自定义的其他参数,则必须实现__init__
3. 使用flask_script应用对象manage.add_command对命令类进行注册,并设置调用终端别名。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask
from flask_script import Command,Option,Manager
app = Flask(__name__)
class Config():
DEBUG = True
app.config.from_object(Config)
class HelloCommand(Command):
def run(self):
print('命令执行了......')
manager = Manager(app)
manager.add_command('hello',HelloCommand)
@app.route('/')
def index():
return 'ok'
if __name__ == "__main__":
manager.run()
终端:python app03.py hello
接收指定的指令参数
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask
from flask_script import Command,Option,Manager
app = Flask(__name__)
class HelloCommand(Command):
option_list = [
#参数1:作为run接受的参数名称,指定的参数名称,参数2:辅助参数名称
Option('--name','-n',help='xxx'),
Option('--num','-m')#多个指令参数
]
def run(self,name,num): #run必须使用参数接受命令参数值
print(name,num)
print('命令执行了......')
manager = Manager(app)
manager.add_command('hello',HelloCommand)
@app.route('/')
def index():
return 'ok'
if __name__ == "__main__":
manager.run()
终端指令:python app03.py hello -n='bobo',python app03.py hello -m=20
创建子应用目录结构:flask的应用其实叫做蓝图(创建一个users的目录,里面存储三个源文件)
from flask import Flask
from flask_script import Manager, Command, Option
app = Flask(__name__)
class Config():
DEBUG = True
app.config.from_object(Config)
manager = Manager(app)
import os
class BluePrintCommand(Command):
option_list = [
Option("--name","-n",help="蓝图名称")
]
def run(self,name=None):
if name is None:
print("蓝图名称不能为空!")
return
if not os.path.isdir(name):
os.mkdir(name)
open("%s/views.py" % name,"w")
open("%s/models.py" % name,"w")
with open("%s/urls.py" % name,"w") as f:
f.write("""from . import views
urlpatterns = [
]
""")
manager.add_command("blue", BluePrintCommand)
@app.route("/")
def index():
return "ok"
if __name__ == '__main__':
manager.run()
终端指令:python app03.py blue --name=users
本文来自博客园,作者:长情不羁的五年,转载请注明原文链接:https://www.cnblogs.com/grlend/articles/14395661.html

浙公网安备 33010602011771号