标签:flask @app.before_request @app.after_request @app.teardown_request
Flask 中 @app.before_request
、@app.after_request
和 @app.teardown_request
flask
中又两种 context
(上下文),分别是 application context
和 request context
。
其中 request
就是 request context
。当 HTTP 请求过来的时候,进入这个上下文。
题主的那些方法都是一些 flaks
的 hooks
。用于针对 request
做一些操作,比如
before_request
:在请求收到之前绑定一个函数做一些事情。
after_request
: 每一个请求之后绑定一个函数,如果请求没有异常。
teardown_request
: 每一个请求之后绑定一个函数,即使遇到了异常。
至于用来干嘛?可以做很多关于request pre
的事情,和request after
的事情。
比如,before_request
的时候创建一个 db
连接,然后 teardown_request
的时候断开这个连接.
def init_db(): with closing(connect_db()) as db: with app.open_resource(‘schema.sql‘) as f: db.cursor().executescript(f.read()) db.commit()
closing() 助手函数允许我们在 with 块中保持数据库连接可 用。应用对象的open_resource() 方法在其方框外也支持这个 功能,因此可以在 with 块中直接使用。这个函数从资源位置(你的 flaskr 文 件夹)中打开一个文件,并且允许你读取它。
我们知道如何在建立数据库连接并且如何执行脚本,但是我们如何能优雅的在请求 中这么做?所有的函数都需要数据库连接,所以在请求之前初始化,在请求结束后自动 关闭就很有意义。
Flask 允许我们用 before_request() 、 after_request() 和 teardown_request() 装饰器来实现这个功能:
@app.before_requestdef before_request(): g.db = connect_db()@app.teardown_requestdef teardown_request(exception): g.db.close()
用 before_request() 装饰的函数会在请求前调用,它没有参 数。用 after_request()装饰的函数在请求结束后调用,需要 传入响应。它们必须返回那个响应对象或是不同的响应对象。但当异常抛出时,它们 不一定会被执行,这时可以使用teardown_request() 装饰器, 它装饰的函数将在响应构造后执行,并不允许修改请求,返回的值会被忽略。如果在 请求已经被处理的时候抛出异常,它会被传递到每个函数,否则会传入一个 None 。
我们把当前的数据库连接保存在 Flask 提供的 g 特殊对象中。这个 对象只能保存一次请求的信息,并且在每个函数里都可用。不要用其它对象来保存信 息,因为在多线程环境下将不可行。特殊的对象 g 在后台有一些神 奇的机制来保证它在做正确的事情。
test_request_context() 方法可以用于 配合 with 声明,用于于激活一个临时的请求上下文。通过 它,您可以访问 request 、g 和 session 类的对象,就像在视图中一样。 这里有一个完整的例子示范了这种用法:
app = flask.Flask(__name__)with app.test_request_context(‘/?name=Peter‘): assert flask.request.path == ‘/‘ assert flask.request.args[‘name‘] == ‘Peter‘
所有其他的访问受限的对象都可以使用同样的方法访问。
在配置中使用类和继承:
class Config(object): DEBUG = False TESTING = False DATABASE_URI = ‘sqlite://:memory:‘class ProductionConfig(Config): DATABASE_URI = ‘mysql://user@localhost/foo‘class DevelopmentConfig(Config): DEBUG = Trueclass TestingConfig(Config): TESTING = True
启用这样的配置你需要调用 from_object()
app.config.from_object(‘configmodule.ProductionConfig‘)
在 Flask 0.8 中,引入了 Flask.instance_path 并提出了“实例文件夹” 的新概念。实例文件夹被为不使用版本控制和特定的部署而设计。这是放置运行时 更改的文件和配置文件的最佳位置。
你可以在创建 Flask 应用时显式地提供实例文件夹的路径,也可以让 Flask 自 动找到它。对于显式的配置,使用 instance_path 参数:
app = Flask(__name__, instance_path=‘/path/to/instance/folder‘)
请注意给出的 一定 是绝对路径。
--------------------------------------------------------------------
实例文件夹的路径可以在 Flask.instance_path 找到。 Flask 也提供了 一个打开实例文件夹中文件的捷径,就是 Flask.open_instance_resource() 。
两者的使用示例:
filename = os.path.join(app.instance_path, ‘application.cfg‘)with open(filename) as f: config = f.read()# or via open_instance_resource:with app.open_instance_resource(‘application.cfg‘) as f: config = f.read()
一个蓝图可以通过 static_folder 关键字参数提供一个指向文件系统上文件夹的路 径,来暴露一个带有静态文件的文件夹。这可以是一个绝对路径,也可以是相对于蓝图 文件夹的路径:
admin = Blueprint(‘admin‘, __name__, static_folder=‘static‘)
默认情况下,路径最右边的部分就是它在 web 上所暴露的地址。因为这里这个文件夹 叫做 static ,它会在 蓝图 + /static 的位置上可用。也就是说,蓝图为 /admin 把静态文件夹注册到 /admin/static 。
最后是命名的 blueprint_name.static ,这样你可以生成它的 URL ,就像你对应用 的静态文件夹所做的那样:
url_for(‘admin.static‘, filename=‘style.css‘)
------------------------------------------
当你想要从一个页面链接到另一个页面,你可以像通常一个样使用 url_for() 函数,只是你要在 URL 的末端加上蓝图的名称和一个点( . )作为前缀:
url_for(‘admin.index‘)
此外,如果你在一个蓝图的视图函数或是模板中想要从链接到同一蓝图下另一个端点, 你可以通过对端点的只加上一个点作为前缀来使用相对的重定向:
url_for(‘.index‘)
这个案例中,它实际上链接到 admin.index ,假如请求被分派到任何其它的 admin 蓝图端点。
本文出自 “智能化未来_XFICC” 博客,请务必保留此出处http://xficc.blog.51cto.com/1189288/1676591
Flask 中 @app.before_request、@app.after_request 和 @app.teardown_request
标签:flask @app.before_request @app.after_request @app.teardown_request
原文地址:http://xficc.blog.51cto.com/1189288/1676591