flask - QLGQ/learning-python GitHub Wiki

Reference

Flask基础教程
Flask教程

虚拟环境

安装 Flask 最便捷的方式是使用虚拟环境。虚拟环境是 Python 解释器的一个私有副本,在这个环境中你可以安装私有包,而且不会影响系统中安装的全局。

安装虚拟环境

Python 解释器 在Linux环境下使用下面的代码安装虚拟环境:

$ sudo apt-get install python-virtualenv

新建一个flask文件夹用来存放工程。然后使用 virtualenv 命令在 flask文件夹中创建 Python 虚拟环境。

$ virtualenv venv

这个命令只有一个必需的参数,即虚拟环境的名字。创建虚拟环境后,当前文件夹中会出现一个子文件 夹,名字就是上述命令中指定的参数,与虚拟环境相关的文件都保存在这个子文件夹中。 按照惯例,一般虚拟环境会被命名为 venv。

激活虚拟环境

Linux用户使用如下命令激活并进入虚拟环境

$ source venv/bin/activate

使用deactivate命令退出虚拟环境

安装flask

在虚拟环境中使用如下命令安装flask模块

(venv) $ pip install flask

程序的基本结构

程序实例的初始化创建

所有 Flask 程序都必须创建一个程序实例。Web 服务器使用一种名为 Web 服务器网关接口(Web Server Gateway Interface,WSGI)的协议,把接收自客户端的所有请求都转交给这个对象处理。程序实例是 Flask 类的对象,经常使用下述代码创建:

from flask import Flask
app = Flask(__name__)

Flask 类的构造函数只有一个必须指定的参数,即程序主模块或包的名字。在大多数程序中,Python 的 name 变量就是所需的值。

构建路由和视图函数

客户端(例如 Web 浏览器)把请求发送给 Web 服务器,Web 服务器再把请求发送给 Flask程序实例。程序实例需要知道对每个 URL 请求运行哪些代码,所以保存了一个 URL 到Python 函数的映射关系。处理URL 和函数之间关系的程序称为路由。可以通过以下代码构建路由:

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

其中函数index()返回的就是一个响应,它是客户端接收到的内容,index()函数就是视图函数。
对于route装饰器,它也可以接受动态信息,例如url地址可能会有诸如用户名之类的可变部分,此时只需要将代码写成:

@app.route('/user/<name>')
def user():
    return '<h1>Hello, %s!</h1>' % name

Tips:路由中的动态部分默认使用字符串,不过也可使用类型定义。例如,路由 /user/int:id只会匹配动态片段 id 为整数的 URL。Flask 支持在路由中使用 int 、 float 和 path 类型。path 类型也是字符串,但不把斜线视作分隔符,而将其当作动态片段的一部分。如果想要查看路由的映射关系,可以使用app.url_map来查看。

启动服务器

通过run()方法启动Web服务器

if __name__ == '__main__':
    app.run(debug = True)

请求和响应

程序请求上下文

Flask 从客户端收到请求时,要让视图函数能访问一些对象,这样才能处理请求。请求对象就是一个很好的例子,它封装了客户端发送的 HTTP 请求。要想让视图函数能够访问请求对象,最直接的方式是将其作为参数传入视图函数,但这会导致程序中的每个视图函数都增加一个参数。除了访问请求对象,如果视图函数在处理请求时还要访问其他对象,情况会变得更糟。
为了避免大量可有可无的参数把视图函数弄得一团糟,Flask 使用上下文临时让特定的变量在一个线程中全局可访问,与此同时却不会干扰其他线程。

from flask import request
@app.route('/')
def index():
user_agent = request.headers.get('User-Agent')
return '<p>Your browser is % s</p>' % user_agent

在上述代码中,request就成了一个全局可访问的对象。
在flask中有两种上下文,应用上下文和请求上下文,上下文变量如下表所示:

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

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()

请求钩子

Flask 提供了注册通用函数的功能,注册的函数可在请求被分发到视图函数之前或之后调用。Flask 支持以下 4 种钩子:

  • before_first_request :注册一个函数,在处理第一个请求之前运行。
  • before_request :注册一个函数,在每次请求之前运行。
  • after_request :注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行。
  • teardown_request :注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行。
    在请求钩子函数和视图函数之间共享数据一般使用上下文全局变量 g 。例如, before_request 处理程序可以从数据库中加载已登录用户,并将其保存到 g.user 中。随后调用视图函数时,视图函数再使用g.user 获取用户。

响应

Flask 调用视图函数后,会将其返回值作为响应的内容。大多数情况下,响应就是一个简单的字符串,作为 HTML 页面回送客户端。但 HTTP 协议需要的不仅是作为请求响应的字符串。HTTP 响应中一个很重要的部分是状态码,Flask 默认设为 200,这个代码表明请求已经被成功处理。
如果视图函数返回的响应需要使用不同的状态码,那么可以把数字代码作为第二个返回值,添加到响应文本之后。例如,下述视图函数返回一个 400 状态码,表示请求无效:

@app.route('/')
def index():
return '<h1>Bad Request</h1>', 400

Flask 视图函数还可以返回 Response 对象。 make_response() 函数可接受 1 个、2 个或 3 个参数(和视图函数的返回值一样),并返回一个 Response 对象。

from flask import make_response
@app.route('/')
def index():
response = make_response('<h1>This document carries a cookie!</h1>')
response.set_cookie('answer', '42')
return response

Application

创建app.py文件

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello World"

if __name__ == "__main__":
    app.run()

这就是一个最简单的Flask应用。我们尝试运行它,然后通过浏览器进行访问。

$ python app.py

此时,只要访问http://127.0.0.1:5000/,就可以看到Hello World。 代码所实现的功能:

  1. 导入Flask类,使用这个类我们可以创建应用。
  2. 创建app,也就是一个Flask应用实例。
  3. 创建index方法,使用app.route装饰器绑定路由规则,当用户访问http://127.0.0.1:5000/时,运行该方法,这样我们在浏览器上看到了返回结果Hello World。
  4. 运行Flask应用。
⚠️ **GitHub.com Fallback** ⚠️