1、Flask简介
一个轻量级的“微内核”Web应用框架,基于Werkzeug实现的WSGI套件和Jinja2模板引擎, 内核精简,易于扩展,花费较少的学习成本,即可能开发一个简单的网站。
相关文档:
- Flask官网:flask.pocoo.org/
- Flask Github仓库:github.com/pallets/fla…
- Flask官方文档:flask.pocoo.org/docs/1.0
- Flask官方文档(中文版):dormousehole.readthedocs.io/en/latest/
- Flask学习资源:github.com/humiaozuzu/…
2、Flask开发环境搭建
直接通过pip命令安装即可:
pip install flask
这里要注意「全局安装」和「虚拟环境安装」的区别,之前有很多读者都问过这样的问题:
我明明在命令行里已经执行了pip install xxx库,但是进去pycharm,还是提示模块找不到?
对此,有两种可选的解决方案:
- 方案一:在PyCharm处的终端处执行pip安装命令(注:前面有个venv)
- 方案二:勾选 inherit global stie-packages
个人更倾向于第一种,为了解决维护不同项目对应不同版本的问题,Python使用了虚拟环境的概念, 在虚拟环境中安装第三方包只会作用到虚拟环境中,全局的Python解释器不受影响。在Python3中, 虚拟环境已成为一个内置模块,创建一个带虚拟环境的文件示例如下:
mkdir Test cd Test python -m venv venv
执行完上述命令后,Python会运行venv包,创建一个venv的虚拟环境,上面的两个venv参数分别为:
- Python虚拟环境包的名称,固定写venv
- 应用于这个特定的虚拟环境的名称,可以改成你喜欢的名字,不过笔者习惯命名为venv,切换到别 的项目时,都能快速的找到对应的虚拟环境。
虚拟环境创建后,需要激活后才能进入,通过下述命令「激活虚拟环境」:
source venv/bin/activate
执行完后会看到终端前缀多了个venv,激活虚拟环境后,终端会话的环境配置就会被修改, 此时键入Python或者pip,实际上调用的都是虚拟环境中的Python解释器。一个应用场景:打开多个终端调试多个应用,每个终端窗口可以激活不同的虚拟环境,且不相互干扰。
注:如果你使用的是Python2或者Windows系统,如果想使用虚拟环境,要先通过pip命令 安装先安装一波virtualenvwrapper:pip install virtualenvwrapper。然后创建虚拟环境:virtualenv venv,最后是激活虚拟环境:venv\Scripts\activate.bat。
3、最简单的Hello Flask
新建一个hello.py的脚本,内容如下:
# coding=utf-8 from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello Flask!" if __name__ == "__main__": app.run()
在终端键入下述命令执行脚本:
python hello.py
运行后可以看到输出如下信息:
浏览器打开:http://127.0.0.1:5000,可以看到如图所示的Hello Flask!
服务启动后就会进入轮询,等待并处理请求,知道程序被终止,也可以直接按Ctrl+C停掉。 接着逐行解析一波代码:
- 第1行:用于声明Python源文件的编码语法,该信息后续会被Python解析器用于解析源文件, 一般统一用utf-8。
- 第2行:引入Flask类。
- 第4行:实例化一个Flask类实例app,该实例接收包或模块名称作为参数,一般直接传入
__name__
, 让flask.helpers.get_root_path函数通过传入这个名字确定程序的根目录,以便获得静态文件和 模板文件的目录。
- 第6-8行:app:route装饰器会将URL和执行的视图函数的关系保存到app.url_map属性上。 这三行简单点说就是:当浏览器访问服务器程序的根地址("/")时,Flask实例执行视图函数hello(), 然后返回:Hello Flask!
- 第10行:其他文件引用此文件时,不会执行这个判断内的代码。
- 第11行:启动服务,默认Flask只监听本地127.0.0.1地址和5000端口,如果你想修改端口,可以 传入参数「port=端口号」,想支持远程访问的话,则传入「host="0.0.0.0"」,你还可以设置 调试模式,只需传入参数「debug=True」,启用调试模式后,服务器会在代码修改后会自动重新 载入,并在发生错误的时候提供一个能获取错误上下文及可执行代码的调试页面。
4、flask-script模块
该模块的作用是:通过命令行的形式来操作Flask,使用命令行传参,而不仅仅是通过 app.run()函数来传。直接通过pip命令即可安装此模块:
pip install flask-script
新建一个manage.py的文件:
from flask_script import Manager from flask import Flask app = Flask(__name__) manager = Manager(app) if __name__ == '__main__': manager.run()
接着命令行键入:
python manage.py runserver -h ip -p 端口
除此之外的参数还有:-d(开启调试模式),-r(代码修改后自动加载),--help(查看帮助信息)。
5、路由与视图
上面这种:
@app.route("/") def hello(): return "Hello Flask!"
定义了URL到Python函数间的映射关系,这种映射关系就叫路由。
0x1 动态路由
有时,可能有一些具有相同规则的URL,比如:
app.route("/login") app.route("/register")
我们可以把这类URL抽象成一个URL模式,示例如下:
@app.route('/<do>') def hello(do): return "<h1>当前请求:%s </h1>" % do
Flask支持这种动态形式的路由,动态部分默认是字符串,你也可以指定参数类型, 比如只接受整数:<int:id>,更多规则如下表所示:
字段标记 | 描述 | 示例 |
string | 默认,接受任何没有斜杆"/"的文本 | <string:name> |
int | 整数 | <in:id> |
float | 浮点数 | <float:price> |
path | 和string类似,但也接受斜杠 | <path:address> |
uuid | 只接受uuid字符串 | <string:uuid> |
any | 可以指定多种路径,但需要传入参数 | <any(int,string):params> |
另外有一点要注意:唯一URL,比如下面代表的是两个不同的URL:
CodingBoy.io/article/ CodingBoy.io/article
0x2 URL构造
在Flask中,可以使用url_for()函数来构造URL,接受一个视图函数名作为第一个参数, 也接受对应URL规则变量部分的命名参数,未知变量部分会被添加到URL末尾作为查询 参数。这里务必注意一点:操作的是函数,不是路由里的路径!!!!通过函数构建,而不是直接用字符串拼接,主要出于下面两个目的:
- 未来需要修改时,只需一次性修改URL,而不用到处替换;
- URL构建会自动转义特殊字符和Unicode数据,而不用我们自己处理;
使用示例如下:
with app.test_request_context(): print(url_for('hello', uid=1)) print(url_for('hello', uid=2, kind='测试'))
输出结果如下:
/?uid=1 /?uid=2&kind=%E6%B5%8B%E8%AF%95
如果你想生成一个绝对路径,可以添加「_external=True」参数。
注:test_request_context可以在交互模式下产生请求上下文,不用app.run() 来运行这个项目,直接执行也会有Falsk上下文
0x3 请求方法限定
HTTP支持多种请求方法,默认情况下,路由只响应GET请求,如果不信可以自行用 PostMan对接口发起一个POST请求,结果如图所示:
响应码是405,表示不允许使用这种请求方法请求此URL,可以直接在 app.route装饰器中设置methods参数来修改。修改后的代码示例如下:
@app.route("/", methods=['GET', 'POST']) def hello(): return "Hello Flask!"
当然也支持其他的请求方法:PUT,HEAD,DELETE,OPTIONS,PATCH,想支持多种方法用逗号隔开即可。