preface
今天我开始自学flask了,由此记录学习中的点点滴滴。
有问题请联系我(Mr.Leo 18500777133@sina.cn)
include:
- 简介flask
- hello world
- 配置管理
- 调试模式
为什么还需学习flask
- 作为一个pythonic,掌握一个web框架远远不够的,所以你需要再次学其他的主流框架
- flask社区很活跃,也是一款主流的框架。
- 与django相比,flask没有提供更多的功能,都是靠开发者自己去选择哪些模块去完成自己需要做的事情,也就是说,微框架的形式给开发者更大的选择空间。
简介flask
-
依赖三个库
1.1. Jinja2: 默认的模版引擎。
1.2. Werkzeug: 一个包含WSGI,路由,调试的工具集。
1.3. Itsdangerous: 基于Django的签名模块(http://bit.ly/28QV7FB)的签名实现。 -
flask本身尽量保持了内核的精简,其设计初衷就是不会为替开发者做太多的决策,而且就替你做了选择,你也可以很容易的替换。举两个例子:
2.1. 对数据库层面的操作,使用SQLAlchemy,MongoEngine,不用ORM而直接基于Mysql-python这样的底层驱动进行开发都是可以的。选择权都在你手中。
2.2. 可以把默认的jinja2模版引擎替换成Mako或者其他模版引擎都是非常容易的。
hello world
都是采用python2.7的版本编写
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=9000)
代码解释下:
from flask import Flask
是引入这个模块app = Flask(__name__)
app是Flask的实例。它接受包或者模块的名字作为参数 ,但是一般我们都是传入__name__
,让flask.helpers.get_root_path
函数通过传入的这个参数确定程序的根目录,以便获得静态文件和模版文件的目录。@app.route('/')
这个相当于django里面的url 匹配一样(url路由系统),在flask里面我们通过app.route装饰器将URL和执行的方法(视图函数)的关系保存到app.url_map属性上。处理URL和视图关系的程序就是路由。app.run(host='0.0.0.0',port=9000)
,执行app.run就可以启动服务器了。默认flask是监听本地的127.0.0.1,端口为5000,我们通过host和port来自己设定指定的地址和端口。当服务器启动后,会调用werkzeug.serving.run_simple 进入轮询,默认使用单进程单线程的werkzeug.serving.BaseWSGIServer 处理请求,实际使用的是标准库BaseHttpServer。HTTPServer,通过select.select做0.5秒的While True事件轮询。- 需要说明的是,app.run启动方法只适合调试,不要再生产环境中使用,生产环境应该使用Gunicorn或者uWSGI。
总结上我们访问的流程:
- 我们访问"http://127.0.0.1:9000",通过app.url_map找到注册的"/"这个URL,就找到了对应的处理方法(hello world)去执行,返回“hello world”,状态码为200,如果访问其他的URL,没有在flask里面注册的话,就会返回404。
配置管理
玩过django的人都知道,django项目里面有settings这个配置文件,我们可以不断的往里添加我们的配置项,但是在Flask里面没有这个东西,怎么办?
- 通过硬编码方式写到代码文件里面,如key=value。
- 通过app.config.方法来添加,支持三种方式来添加:
2.1. 直接在代码文件里面通过app.config.update方法添加,app.config.update是继承了Python内置数据结构的dict。如下所示:
app.config.update(
DEBUG=True,
FUCK='shit',)
2.2. 我们可以把配置单独写到一个配置文件里面,假设这个文件名为settings,文件内容如下:
A=1
B=2
那么我们可以通过三种方式来加载
2.2.1. 通过配置文件加载
# 1. 直接通过字符串的模块名字引入:
app.config.from_object('settings')
# 2. 引入之后直接传入模块对象:
import settings
app.config.from_object(settings)
2.2.2. 通过文件名加载。直接传入文件名字,但是不限于只用py为后缀的文件名:
app.config.from_pyfile('settings.py',silent=True) # 默认配置文件不存在的时候会抛出异常,使用silent=True的时候只是返回False,但是不会抛出异常。
2.2.3. 通过环境变量加载。这种方式依赖支持silent参数,获得路径后其实还是使用from_pyfile的方式加载。
>export YOURAPPLICATION_SETTINGS='settings.py' # 这里在shell下export一个变量
app.config.from_envar('YOURAPPLICATION_SETTINGS')
调试模式
虽然app.run这样的方式适用于启动本地的开发服务器,但是每次修改完代码都是人工手动重启一次,那么为了方便让她自动重启在修改完代码之后,我们可以这样,开启调试模式,那么Flask会自动重启当你修改完代码之后,并在错误时提供一个能获得错误上下文以及可以执行代码的调试页面。
我们有两种途径来启用调试模式:
- 直接在应用对象上设置:
app.debug = True
app.run()
- 作为run参数传入
app.run(debug=True)
需要注意点是,开启调试模式会成为一个巨大的安全隐患,因此他绝对不可以用于生成环境下。 Werkzeug从0.11版本开始默认启用 PIN(Persoanl Identification Number)码的身份验证,旨在调试环境下的攻击者更难利用调试器。启动程序的时候可以看到类似这样的:
* Running on http://0.0.0.0:9000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 340-109-987 # 就是这个PIN码
当程序有异常进入错误堆栈模式的时候,第一次点击某个堆栈想看对应的变量的值的时候,就需要输入PIN码,PIN码默认过期时间是8小时,时效之前不需要重复输入。
当然也可以这样设置PIN码的值
WERKZEUG_DEBUG_PIN = 123456