Flask web程序基本结构 - littleboy12580/learning_python GitHub Wiki

Flask的安装

安装虚拟环境

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

$ sudo apt-get install python-virtualenv

新建一个flask文件夹用来存放工程。然后使用 virtualenv 命令在 flasky 文件夹中创建 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

请求上下文

请求对象,封装了客户端发出的HTTP请求中的内容

session

请求上下文

用户会话,用于存储请求之间需要“记住”的值的字典

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

上述代码创建了一个响应对象,然后设置了 cookie

⚠️ **GitHub.com Fallback** ⚠️