1 基本介绍
Flask 自开发伊始就被设计为可扩展的框架,它具有一个包含基本服务的强健核心,其他功能则可通过扩展实现。
Flask 有 3 个主要依赖:路由、调试和 Web 服务器网关接口
2 应用的基本结构
所有 Flask 应用都必须创建一个应用实例。
from flask import Flask
app = Flask(__name__)
路由和视图函数
客服端发送请求到服务器,服务器把请求发送给flask应用实例。应用实例保存url到python函数的映射关系,不同函数处理不同url请求。而处理这种映射关系的关系称之为路由。
- 使用装饰器注册路由函数:index函数注册为根目录的处理程序
@app.route(‘/‘)
def index():
return ‘<h1>Hello world!</h1>‘
- 传统方式:
app.add_url_rule
def index():
return ‘<h1>Hello world!</h1>‘
app.add_url_rule(‘/‘,‘index‘,index) # URL 端点名 视图函数
视图函数的返回值称为响应,为客户端接收到的内容
- URL中的可变内容
@app.route(‘/user/<name>‘) # <>内动态部分
def index():
return ‘<h1>Hello {}</h1>‘.format(name)
路由 URL 中放在尖括号里的内容就是动态部分,任何能匹配静态部分的 URL 都会映射到这个路由上。调用视图函数时,Flask 会将动态部分作为参数传入函数。
路由中的动态部分默认使用字符串。
Flask 支持在路由中使用 string、int、float 和 path 类型。path 类型是一种特殊的字符串,与 string 类型不同的是,它可以包含正斜线。
/user/<int:id> 只会匹配动态部分id为整数的URL
简单应用和Web服务启动
from flask import Flask
app = Flask(__name__)
@app.route(‘/‘)
def index():
return ‘<h1>Hello world!</h1>‘
Flask 应用自带 Web 开发服务器,通过 flask run 命令启动。
这个命令在 FLASK_APP 环境变量指定的 Python 脚本中寻找应用实例。
Windows下:
-
确保激活所在Flask所在环境
-
执行命令
set FLASK_APP = hello.py # 自己的实例py文件
flask run
或者可以在py脚本加上
app.run()
目前只是开发状态
动态路由
在前面的基础上利用动态部分来实现访问动态URL
调试模式
Flask 应用可以在调试模式中运行。在这个模式下,开发服务器默认会加载两个便利的工具:重载器和调试器。
-
重载器:启用重载器后,Flask 会监视项目中的所有源码文件,发现变动时自动重启服务器。每次修改并保存源码文件后,服务器都会自动重启,让改动生效。
-
调试器:调试器是一个基于 Web 的工具,当应用抛出未处理的异常时,它会出现在浏览器中。此时,Web 浏览器变成一个交互式栈跟踪,你可以在里面审查源码,在调用栈的任何位置计算表达式。
调试模式默认关闭,在flask run
之前需要设置FLASK_DEBUG=1环境变量。
set FLASK_DEBUG=1 # Windows环境下set设置环境变量
命令行选项
这里只是告诉大家有一些选项参数可以选择或帮助我们后续的使用:
flask命令支持一些参数选项 flask shell
flask run
的--host
参数告诉Web服务器在哪个网络接口监听客户端的连接。默认监听localhost的连接,即只接受运行Web服务器的计算机的连接请求。
flask run --host 0.0.0.0
接受同一网络中所有计算机的连接请求
请求-响应循环 (简单介绍HTTP)
应用和请求上下文
Flask从客户端收到请求,视图函数通过访问请求对象来获取信息处理请求。
Flask 使用上下文临时把某些对象变为全局可访问。
from flask import request
@app.route(‘/‘)
def index():
user_agent = request.headers.get(‘User-Agent‘)
return ‘<p>Your browser is {}</p>‘.format(user_agent)
这里例子把request当作全局变量使用
多线程 Web 服务器会创建一个线程池,再从线程池中选择一个线程处理接收到的请求。
上下文:应用上下文和请求上下文。举例:
变量名 | 上下文 | 说明 |
---|---|---|
current_app | 应用上下文 | 当前应用的应用实例 |
g | 应用上下文 | 处理请求时用作临时存储的对象,每次请求都会重设这个变量 |
request | 请求上下文 | 请求对象,封装了客户端发出的 HTTP 请求中的内容 |
session | 请求上下文 | 用户会话,值为一个字典,存储请求之间需要“记住”的值 |
Flask 在分派请求之前激活(或推送)应用和请求上下文,请求处理完成后再将其删除。
应用上下文被推送后,就可以在当前线程中使用 current_app 和 g 变量。同理,请求上下文被推送后,就可以使用 request 和 session 变量。如果使用这些变量时没有激活应用上下文或请求上下文,就会导致错误。
请求分派
应用收到客户端发来的请求时,要找到处理该请求的视图函数。为了完成这个任务,Flask会在应用的 URL 映射中查找请求的 URL。URL 映射是 URL 和视图函数之间的对应关系。
Flask构建映射:
-
app.route
装饰器 -
app.add_url_rule
方法
查看Flask应用中的映射:
app.url_map
# python shell下
>>> from hello import flask
>>> app.url_map
URL 映射中的 (HEAD, OPTIONS, GET) 是请求方法,由路由进行处理。HTTP 规范中规定,每个请求都有对应的处理方法,这通常表示客户端想让服务器执行什么样的操作。Flask为每个路由都指定了请求方法,这样即使不同的请求方法发送到相同的 URL 上时,也会使用不同的视图函数处理。HEAD 和 OPTIONS 方法由 Flask 自动处理
请求对象
Flask 通过上下文变量 request 对外开放请求对象,包含客户端发送的 HTTP 请求的全部信息。
具体常用的属性和方法暂时略
page36
请求钩子
有时在处理请求之前或之后执行代码会很有用。
比如:在请求开始时,我们可能需要创建数据库连接或者验证发起请求的用户身份。
为了避免在每个视图函数中都重复编写代码,Flask 提供了注册通用函数的功能,注册的函数可在请求被分派到视图函数之前或之后调用。
请求钩子通过装饰器实现,目前flask支持如下4种:
-
before_request
:注册一个函数,每次请求前运行 -
before_firest_request
:注册一个函数,只在处理第一个请求前运行 -
after_request
:注册一个函数,如果没有未处理的异常抛出,每次请求之后运行。 -
teardown_request
:注册一个函数,即使有未处理的异常抛出,每次请求之后运行。
在请求钩子函数和视图函数之间共享数据一般使用上下文全局变量 g。例如,before_request 处理程序可以从数据库中加载已登录用户,并将其保存到 g.user 中。随后调用视图函数时,便可以通过g.user 获取用户
响应
Flask 调用视图函数后,会将其返回值作为响应的内容(响应报文的主体)。多数情况下,响应就是一个简单的字符串,作为 HTML 页面回送客户端。
但 HTTP 协议需要的不仅是作为请求响应的字符串。HTTP 响应中一个很重要的部分是状态码,Flask 默认设为 200,表明请求已被成功处理。
视图函数的返回:
- 如果视图函数返回的响应需要使用不同的状态码,可以把数字代码当作第二个返回值
@app.route(‘/‘)
def index():
return ‘<h1>hello world</h1>‘,400
- 视图函数的返回还可以接受第三个参数,这是一个由 HTTP 响应首部组成的字典
- 视图函数如果不想返回由 1 个、2 个或 3 个值组成的元组,Flask 视图函数还可以返回一个响应对象。
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
make_response() 函数可接受 1 个、2 个或 3 个参数,然后返回一个等效的响应对象。有时我们需要在视图函数中生成响应对象,然后在响应对象上调用各个方法,进一步设置响应。
page37
响应有个特殊的类型,称为重定向。这种响应没有页面文档,只会告诉浏览器一个新URL,用以加载新页面,重定向经常在 Web 表单中使用。
重定向的状态码通常是 302,在 Location 首部中提供目标 URL。
-
重定向响应可以使用 3个值形式的返回值生成,也可在响应对象中设定。
-
由于重定向响应使用频繁,提供了redirect() 辅助函数。
from flask import redirect
@app.route(‘/‘)
def index():
return redirect(‘http://www.example.com‘)
还有一种特殊的响应由 abort() 函数生成,用于处理错误。
from flask import abort
@app.route(‘/user/<id>‘)
def get_user(id):
user = load_user(id)
if not user:
abort(404)
return ‘<h1>Hello, {}</h1>‘.format(user.name)
abort() 不会把控制权交还给调用它的函数,而是抛出异常
flask拓展
Flask 的设计考虑了可扩展性,故而没有提供一些重要的功能,例如数据库和用户身份验证,所以开发者可以*选择最适合应用的包,或者按需求自行开发。
所有学习内容基于《Flask Web开发:基于Python的Web应用开发实战》