Flask Web开发入门笔记(二)

1 Flask开启调试模式

Flask 应用可以在调试模式中运行。在这个模式下,开发服务器默认会加载两个便利的工具:重载器调试器
启用重载器后, Flask 会监视项目中的所有源码文件,发现变动时自动重启服务器。在开发过程中运行启动重载器的服务器特别方便,因为每次修改并保存源码文件后,服务器都会自动重启,让改动生效。
调试器是一个基于 Web 的工具,当应用抛出未处理的异常时,它会出现在浏览器中。此时, Web 浏览器变成一个交互式栈跟踪,你可以在里面审查源码,在调用栈的任何位置计算表达式。

Flask Web开发入门笔记(二)_第1张图片
调试器界面

调试模式默认禁用。若想启用,在执行 flask run 命令之前设定 FLASK_DEBUG=1 环境变量:

(venv) $ export FLASK_APP=hello.py
(venv) $ export FLASK_DEBUG=1
(venv) $ flask run
* Serving Flask app "hello"
* Forcing debug mode on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 273-181-528

注意:
当使用 app.run() 方法启动服务器时,不会用到 FLASK_APP 和 FLASK_DEBUG 环境变量。若想以编程的方式启动调试模式,就使用app.run(debug=True)

2 应用和请求上下文

Flask从客户端收到请求时,要让视图函数能访问一些对象,这样才能处理请求。请求对象就是一个很好的例子,它封装了客户端发送的HTTP 请求。
要想让视图函数能够访问请求对象,一种直截了当的方式是将其作为参数传入视图函数,不过这会导致应用中的每个视图函数都多出一个参数。除了访问请求对象,如果视图函数在处理请求时还要访问其他对象,情况会变得更糟。
为了避免大量可有可无的参数把视图函数弄得一团糟, Flask 使用上下文临时把某些对象变为全局可访问。有了上下文,便可以像下面这样编写视图函数:

from flask import request
@app.route('/')
def index():
    user_agent = request.headers.get('User-Agent')
    return '

Your browser is {}

'.format(user_agent)

注意,在这个视图函数中我们把 request 当作全局变量使用。事实上, request 不可能是全局变量。试想,在多线程服务器中,多个线程同时处理不同客户端发送的不同请求时,每个线程看到的 request 对象必然不同。 Flask 使用上下文让特定的变量在一个线程中全局可访问,与此同时却不会干扰其他线程。

在 Flask 中有两种上下文: 应用上下文和请求上下文。下表 列出了这两种上下文提供的变量。

变量名 上下文 说明
current_app 应用上下文 当前应用的应用实例
g 应用上下文 处理请求时用作临时存储的对象,每次请求都会重设这个变量
request 请求上下文 请求对象,封装了客户端发出的 HTTP 请求中的内容
session 请求上下文 用户会话,值为一个字典,存储请求之间需要“记住”的值

Flask 在分派请求之前激活(或推送)应用和请求上下文,请求处理完成后再将其删除。应用上下文被推送后,就可以在当前线程中使用current_appg变量。类似地,请求上下文被推送后,就可以使用 request 和 session 变量。如果使用这些变量时没有激活应用上下文或请求上下文,就会导致错误。

下述 Python shell 会话演示了应用上下文的使用方法:

>>> from hello import app
>>> from flask import current_app
>>> current_app.name
Traceback (most recent call last):
...
RuntimeError: working outside of application context
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name
'hello'
>>> app_ctx.pop()

在这个例子中,没激活应用上下文之前就调用 current_app.name 会导致错误,但推送完上下文之后就可以调用了。注意,获取应用上下文的方法是在应用实例上调用 app.app_context()

你可能感兴趣的:(Flask Web开发入门笔记(二))