2.1 初始化:所有Flasky程序都要创建一个程序实例,web服务器使用web服务器网关接口把接受自客户端的所有请求都转交给这个Flasky类对象处理。
from flask import Flasky
app = Flask(_name_)
在python中,_name_变量就是所需的值
2.2 路由和视图函数
浏览器发请求到服务器。服务器发请求到Flasky程序实例,程序实例保存URL到python函数的映射关系,即路由。
Flasky定义路由,使用程序实例提供的app.route修饰器把函数注册为路由:
@app.route(‘/’)
def index();
return ‘<h1>Hello World!</h1>’
例子即index()函数注册为程序根地址的处理程序。当访问部署的地址时,函数返回值即为响应,函数即为视图函数。
@app.route(‘/user/<name>’)
def user(name):
return ‘<h1>Hello,%s!</h1>’ % name
尖括号为动态部分,默认字符串,支持<int:id>还有float和path,Flasky将动态部分作为参数传入函数。
2.3 启动服务器
run方法启动Flasky集成的开发web服务器
if _name_ == ‘_main_’:
app.run(debug=True)
这里_name_ == ‘_main_’是确保直接执行这个脚本才启动开发web服务器;debug=True启用调试模式。
2.4
2.4.1 一个完整的程序
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
if __name__=='__main__':
app.run(debug=True)
使用python解释器解释
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
浏览器打开http://127.0.0.1:5000/即可Hello World!
2.4.2 另一个完整的包含动态路由的程序
#coding=utf8
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
@app.route('/user/<name>')
def user(name):
return '<h1>Hello,%s!</h1>' %name
if __name__=='__main__':
app.run(debug=True)
使用python解释器解释
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
浏览器打开http://127.0.0.1:5000/为根目录,显示Hello World!;浏览器打开http://127.0.0.1:5000/user/Jorson为子目录,显示Hello,Jorson!
2.5.1 请求-响应循环
2.5.1.1 请求上下文(request\session)
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让特定变量在一个线程中全局可访问。
2.5.1.2 程序上下文(current_app\g)
Flask在分发请求之前激活程序和请求上下文,处理完成再删除。调用app.app_context()可获得一个程序的上下文。
2.5.2 请求调度
URL映射是URL和视图函数之间的对应关系。Flask使用app.route修饰器或者非修饰器形式的app.add_url_rule()生成映射。
查看hello.py生成的映射:
(venv) C:\Windows\System32\flasky>python
>>> from hello import app
>>> app.url_map
Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])
其中,/和/user/<name>使用app.route修饰器定义,/static/<filename>路由是特殊路由用于访问静态文件。每个路由都有HEAD,Options,GET请求方法,对应不同的视图函数。HEAD和OPTIONS方法由Flask自动处理,因此以上的程序中,URL映射的三个路由都使用GET方法。
2.5.3 请求钩子
Flask提供注册通用函数的功能,可在请求前后调用,请求钩子使用修饰器实现:
before_first_request:注册一个函数,在处理第一个请求之前运行
before_request:注册一个函数,在每次请求之前运行
after_request:注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行
teardown_request:注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行
请求钩子函数和视图函数之间共享数据一般使用上下文全局变量g,例如before_request处理程序可以从数据库加载已登陆用户,保存在g.user中,随后调用视图函数再使用g.user获取用户。
2.5.4 响应
2.5.4.1 返回元组
HTTP响应的很重要的部分是状态码,Flask默认为200表明请求已成功处理。若使用其他数字代码则可以作为第二个返回值
@app.route('/')
def index():
return '<h1>Bad</h1>',400
2.5.4.2 返回对象
除了返回1,2,3个值组成的元组, Flask还可以返回Request对象。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
2.5.4.3 重定向
特殊响应类型,无页面文档,只告诉浏览器一个新地址用于加载新页面。常用于web表单。重定向常使用302状态码,指向地址由location首部提供。重定向响应可以使用3个值形式的返回值生成,也可以在Response对象中设定,也用于redirect()辅助函数:
from flask import redirect
@app.route('/')
def index():
return redirect('http://www.example.com')
2.5.4.4 处理错误的响应
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,%s</h1>' % user.name
注意:abort直接抛出异常
2.6 Flask扩展
Flask支持大量扩展,包括Python标准包和代码库。
2.6.1 Flask-Script支持命令行选项
Flask的开发web服务器支持很多启动选项,在脚本中作为参数传给app.run()不方便,可以使用命令行参数。
Flask-Script是一个Flask扩展,为Flask程序添加了一个命令行解析器,自带一组常用选项,支持自定义命令。
安装Flask-Script:pip install flask-script
from flask import Flask
from flask_script import Manager
app = Flask(__name__)
manager = Manager(app)
@app.route('/')
def index():
return '<h1>Hello World!</h1>'
@app.route('/user/<name>')
def user(name):
return '<h1>Hello, %s!</h1>' % name
if __name__ == '__main__':
manager.run()
运行代码可以使用一组基本命令行选项
shell:在程序上下文中启动Python shell会话,进行运行维护任务或测试、调试
runserver:启动web服务器,调试模式
--host:参数,告诉web服务器在哪个网路接口上监听来自客户端的连接,默认监听本地连接,使用下述命令来监听公共网络接口的连接:
python hello.py runserver --host 0.0.0.0