Flask介绍(轻量级的框架,非常快速的就能把程序搭建起来)
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。
“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。
默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同是 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已准备好在需求繁杂的生产环境中投入使用。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
- 和django的比较
django:无socket,依赖第三方模块wsgi,中间件,路由系统(CBV,FBV),视图函数,ORM。cookie,session,Admin,Form,缓存,信号,序列化。。
Flask:无socket,中间件(扩展),路由系统,视图(CBV)、第三方模块(依赖jinja2),cookie,session弱爆了
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello World' if __name__ = '__main__': app.run()
剖析上述代码:
1. 首先,我们导入了类 Flask 。这个类的实例化将会是我们的 WSGI 应用。第一个参数是应用模块的名称。 如果你使用的是单一的模块(就如本例),第一个参数应该使用 __name__。因为取决于如果它以单独应用启动或作为模块导入, 名称将会不同 ( '__main__' 对应于实际导入的名称)。
2. 接着,我们创建一个该类的实例。我们传递给它模块或包的名称。这样 Flask 才会知道去哪里寻找模板、静态文件等等。
3. 之后,我们使用装饰器 route() 告诉 Flask 哪个 URL 才能触发我们的函数。这也就是路由,博文之后会详细学习。
4. 之后 ,定义一个函数,该函数名也是用来给特定函数生成 URLs,并且返回我们想要显示在用户浏览器上的信息。
5. 最后,我们用函数 run() 启动本地服务器来运行我们的应用。if __name__ == '__main__': 确保服务器只会在该脚本被 Python 解释器直接执行的时候才会运行,而不是作为模块导入的时候。
服务器外部可见:
目前服务器 仅可本机 localhost 访问,这是因为默认情况下,调试模式,应用中的一个用户可以执行你计算机上的任意 Python 代码。
如果你关闭 debug 或者信任你所在网络上的用户,你可以让你的服务器对外可用,只要简单地改变方法 run() 的调用像如下这样:
app.run(host='0.0.0.0') 这让你的操作系统去监听所有公开的 IP。
调试模式
有两种方式开启调式模式:加入语句,应用对象上设置标志位: app.debug = True
或者作为 run 的一个参数传入: app.run(debug=True) 作为 run 的一个参数传入。
调试模式有安全隐患,决不可在生产环境使用,参考如下:
Attention
Even though the interactive debugger does not work in forking environments (which makes it nearly impossible to use on production servers), it still allows the execution of arbitrary code. This makes it a major security risk and therefore it must never be used on production machines.
Flask 路由
所谓 路由,即 URL 绑定; Flask 使用 route()
装饰器把一个函数绑于一个URL上, 如下:
1 from flask import Flask 2 app = Flask(__name__) 3 4 @app.route('/') 5 def indexPage(): 6 return 'Index Page' 7 8 @app.route('/flask') 9 def flaskPage(): 10 return 'Flask Page' 11 12 if __name__ == '__main__': 13 app.run()
如上示例,把 "/" url 绑了indexPage() 函数,把"/flask" url 绑了flaskPage() 函数。
HTTP请求模拟工具:这边需要使用到HTTP请求工具来查看,chrome可用插件postman;firefox可用HttpRequest。具体使用这边就不介绍了,很简单。
运行后,请求url 以及
以上仅是最简单的url构造,你可以动态地构造 URL 的特定部分,也可以在一个函数上附加多个规则。之后会具体介绍。
变量规则
给 URL 增加变量的部分,把一些特定的字段标记成 <variable_name>。这些特定的字段将作为参数传入到你的函数中。
当然也可以指定一个可选的转换器通过规则 <converter:variable_name>。
先看以下示例(之后示例均省略上下文代码):
@app.route('/user/<username>') def show_user_profiile(username): # show the user profile for that user return 'User: {0}'.format(username)
即简单的URL增加变量,运行后请求的URL需带参数
变量规则
给 URL 增加变量的部分,把一些特定的字段标记成 <variable_name>。这些特定的字段将作为参数传入到你的函数中。
当然也可以指定一个可选的转换器通过规则 <converter:variable_name>。
先看以下示例(之后示例均省略上下文代码):
@app.route('/user/<username>') def show_user_profiile(username): # show the user profile for that user return 'User: {0}'.format(username)
即简单的URL增加变量,运行后请求的URL需带参数
存在如下转换器: ,示例代码如下:
@app.route('/userid/<int:user_id>') def show_userId(user_id): # show the user_id, the id is an integer return 'User ID: {0}'.format(user_id)
URL 须在 "/userid/" 后传递一个整数,运行后如
HTTP 方法
默认情况,创建的URL路由是Get方法,可在通过给 route() 装饰器提供 methods 参数来改变 HTTP 方法,有关HTTP协议相关,请Google相关文档。
@app.route("/postUser", methods=["POST"]) def hello_user(): return "Post User"
上述示例即为一 Post 方法的路由,运行后直接访问会报405,因为该请求方式 应为 Post,这边使用 FireFox 插件 HttpRequester 来模拟
更改为 Post 方式,
最常用的方式即 Post 和 Get,其他的还有 Delete、Put 等,需用时请阅相关的文档。
Request 参数
须要引入request from flask import Flask, request ,来进行request参数的传值,具体示例如下:
@app.route("/query_user") def query_user(): userId = request.args.get("id") return "query user: {0}".format(userId)
有没有很熟悉? 再看下多参数的,如下例:
@app.route("/query_page") def query_page(): pageid = request.args.get("pageid") num = request.args.get("num") return "query page: {0} and {1}".format(pageid,num)
(该部分仅简单介绍,后续会具体学习)