Flask是一个相对于Django而言轻量级的Web框架。css
和Django大包大揽不一样,Flask创建于一系列的开源软件包之上,这其中 最主要的是WSGI应用开发库Werkzeug和模板引擎Jinja:html
策略 :werkzeug和Jinja这两个库和Flask同样,都是pocoo团队开发的。这 或许体现了pocoo与Django竞争时关于生态的一种策略,这种策略的天然 延伸是Flask框架中没有包含数据库方面的构件,不管ORM仍是其余。jquery
关注点 :Flask是一个WSGI应用框架,这意味着咱们进行Flask开发时,不须要 关注网络方面的操做,Flask应用的入口是封装过的网络请求包,出口是 网络响应,咱们仅须要关注这个阶段内的处理逻辑。web
WSGI服务器 :Flask虽然内置了简单的WSGI服务器,但其性能仅仅适用于开发期的调试。 Flask官网推荐了多种WSGI服务器,实现方式从多进程到多线程到协程, 这方面的选择咱们在本课程中将不涉及。数据库
REST适应性 :虽然Flask和Django同样,最初的出发点都是服务端的动态网页应用。但 Flask的设计使之也至关适用于面向资源的REST架构,在愈来愈移动化 而且单页应用愈来愈重要的WEB开发领域,这是Flask相对于Django至关 大的优点。json
编写一个基于Flask的hello world至关容易:flask
一、导入Flask类服务器
from flask import Flask
Flask类是Flask框架的核心类,它实现了WSGI应用规范。网络
二、建立Flask实例多线程
app = Flask(__name__)
Flask构造函数的第一个参数指定一个引入名/import_name。Flask框架 使用这个名字进行静态资源、模板、错误信息的定位。除非你清楚的理解它的 做用,一般状况下,咱们总应该使用特殊变量__name__。
Flask实例是可调用的(具备__call__方法),这个实例能够直接对接 WSGI服务器。
三、注册路由
@route('/') def index(): return 'Hello,Flask!'
注册路由就是创建URL规则和处理函数之间的关联。Flask框架依赖于路由 完成HTTP请求的分发。
路由中的函数被称为视图函数,其返回值将做为HTTP响应的正文内容。
四、对接并启动WSGI服务器
Flask封装了一个简单的开发用WSGI服务器,咱们能够经过调用run() 启动服务器运行:
app.run(host='0.0.0.0',port=80)
路由是MVC架构的Web框架中至关重要的一个概念,也是本节课程的重点。
顾名思意,路由就是在迷茫中找出一条路的意思。在Flask框架中,路由就表示为用户请求的URL找出其对应的处理函数之意。
在本节课程,咱们将主要从如下几个方面讲解Flask框架中的路由:
如何为应用注册路由? 如何为路由指定其支持的HTTP方法? 如何匹配动态URL? 如何对URL中的变量类型进行过滤? 如何理解访问点/endpoint? 如何为应用设定静态路由? 如何避免硬编码指向其余视图的URL?
在Flask应用中,路由是指用户请求的URL与视图函数之间的映射。Flask框架 根据HTTP请求的URL在路由表中匹配预约义的URL规则,找到对应的视图函数, 并将视图函数的执行结果返回WSGI服务器:
可见路由表在Flask应用中处于至关核心的位置。路由表的内容是由应用开发者填充。
route装饰器 :可使用Flask应用实例的route装饰器将一个URL规则绑定到 一个视图函数上。
例如,下面的示例将URL规则/test绑定到视图函数test()上:
@app.route('/test') def test(): return 'this is response'
若是这个应用部署在主机ezhost.com的根目录下,那么当用户访问:
http://ezhost.com/test
Flask框架就会调用咱们的test()函数,其返回结果就传递给WSGI服务器发送给访问者。
add_url_rule() :另外一种等价的写法是使用Flask应用实例的add_url_route()方法。 下面的示例注册了一个与前例相同的路由:
def test(): return 'this is response' app.add_url_route('/test',view_func=test)
其实,route装饰器内部也是经过调用add_url_route()方法实现的路由注册。 可是显然,使用装饰器使代码看起来更优雅一些。
默认状况下,Flask路由仅支持HTTP的GET请求。可使用methods关键字参数,在注册 路由时显式地声明视图方法支持的HTTP方法。
例如,下面的示例将URL规则/auth绑定到视图函数v_auth(),这个路由仅支持POST方法:
@app.route('/auth',methods=['POST']) def v_auth():pass
指定多种HTTP方法支持
关键字参数methods的类型为list,所以能够同时指定多种HTTP方法。
下面的示例中,使URL规则/user同时支持POST方法和GET方法:
@app.route('/user',methods=['POST','GET']) def v_users(): if request.method == 'GET': return ... # 返回用户列表 if request.method == 'POST' return ... #建立新用户
这个特性使Flask很是易于开发REST架构的后台服务,而不只仅局限于传统的动态网页。
有时咱们须要将同一类URL映射到同一个视图函数处理,好比,使用同一个视图函数 来显示不一样用户的我的档案。咱们但愿如下的URL均可以分发到同一个视图函数:
在Flask中,能够将URL中的可变部分使用一对小括号<>声明为变量, 并为视图函数声明同名的参数:
@app.route('/user/<uname>') def v_user(uname): return '%s\'s Profile' % uname </uname>
在上面的示例中,URL规则中的<uname>表示这部分是可变的,Flask将提取用户请求的 URL中这部分的内容,并做为视图函数v_user()的uname参数进行调用。
考虑下面的示例,咱们但愿经过HTTP共享文件夹/var/readonly中的文件:
/var /readonly /a.txt /b.txt /repo /c.txt /d.txt
简单思考一下就有答案了。咱们能够构造URL规则/file/<fname>,而后直接 读取文件内容返回给用户。注册以下的路由:
@app.route('/file/<fname>') def v_file(fname): fullname = os.path.join('/var/readonly',fname) f = open(fullname) cnt = f.read() f.close() return cnt </fname>
测试结果代表,/file/a.txt和/file/b.txt都没有问题,可是/file/repo/c.txt和 /file/repo/d.txt却会失败。
这是由于,默认状况下,在URL规则中的变量被视为不包含/的字符串。/file/repo/c.txt 是没有办法匹配URL规则/file/<fname>的。
可使用内置的path转换器告诉Flask框架改变这一默认行为。path转换器容许 规则匹配包含/的字符串:
@app.route('/file/<path:fname>') </path:fname>
在Flask中,转换器/converter用来对从URL中提取的变量进行预处理,这个过程 发生在调用视图函数以前。Flask预置了四种转换器:
咱们一直强调,路由的做用是根据请求的URL,找到对应的视图函数。这没错,可是在 Flask框架中,请求任务的分发并非直接从用户请求的URL一步定位到视图函数, 二者之间隔着一个访问点/endpoint。
如下面的代码为例,咱们看Flask怎样实现请求的分发:
@app.route('/home') def home():pass
在Flask内部使用两张表维护路由:
以用户访问URL/home为例,Flask将首先利用url_map找到所请求URL对应的 endpoint,即访问点home,而后再利用view_functions表查找home这个访问点 对应的视图函数,最终匹配到函数home():
默认访问点 :当咱们使用route装饰器注册路由时,默认使用被装饰函数的 函数名(name)做为访问点,所以,你看到上面的表中,路由中的访问点为home。
自定义访问点 :能够在使用route装饰器或调用add_url_rule()方法注册路由时,使用 endpoint关键字参数改变这一默认行为:
@app.route('/home',endpoint='whocare') def home():pass
此时的两张路由表将变成这样:
当建立应用实例时,Flask将自动添加一条静态目录路由,其访问点 始终被设置为static,URL规则默认被设置为/static,本地路径默认被 设置为应用文件夹下的static子文件夹:
+------------------------------------------------------------+ | url rule | endpoint | view_function | | /static | static | Flask.send_static_file | +------------------------------------------------------------+ 若是你的应用目录以下:
/app /web.py /static /main.css /jquery.min.js
那么启动应用后就能够经过URL/static/main.css访问static文件夹下的main.css了。
除了访问点被固定为static,静态目录的URL规则和本地目录都是能够根据应用状况进行调整。
改变默认的本地路径 :能够在建立应用对象时使用关键字参数static_folder改变 默认的静态文件夹。例如,你的静态文件都存放在应用下的assets目录下, 那么能够按以下的方式建立应用对象:
app = Flask(name,static_folder='assets') 也可使用一个绝对路径:
app = Flask(name,static_folder='/var/www/static') 改变默认的本地路径并不会对路由表产生影响。
改变默认的URL规则 : 若是不喜欢静态目录URL/static,也能够在建立应用 对象时使用关键字参数static_url_path换一个别的名字。
下面的示例中,将应用下的assets文件夹注册为静态目录/assets:
app = Flask(name,static_folder='assets',static_url_path='/assets') 当应用运行后,经过URL/assets/main.css就能够访问assets文件夹下的 main.css文件了。
这时的路由表变化为:
+------------------------------------------------------------+ | url | endpoint | view_function | | /assets | static | Flask.send_static_file | +------------------------------------------------------------+
在一个实用的视图中,不可避免地存在指向其余视图的连接。在以前的课程示例中,咱们 都是在视图函数中这样硬编码这些连接URL的:
@app.route('/') def v_index(): return '<a href="/tech">tech</a>' @app.route('/tech') def v_tech():pass
大部分状况下这种硬编码URL是能够工做的。但若是这个应用被挂在WSGI服务器的一个 子路径下,好比:/app1,那么用户访问URL/tech是不会成功的,这时应当访问/app1/tech 才能够正确地路由到视图函数v_tech()。
咱们应当使用访问点让Flask框架帮咱们计算连接URL。简单地给url_for()函数传入 一个访问点,它返回将是一个可靠的URL地址:
@app.route('/') def v_index(): print url_for('v_contacts') # /contact return 'see console output!' @app.route('/contact') def v_contacts():pass
添加查询参数 : 使用关键字参数,能够在构造的URL中生成查询串。下面的调用将生成 /contact?format=json
@app.route('/') def v_index(): print url_for('v_contacts',format='json') return '' @app.route('/contact') def v_contacts():pass
添加URL变量 : 若是指定访问点对应的视图函数接收参数,那么关键字参数将生成对应的参数URL。下面的 示例将生成/contact/Julia?format=html:
@app.route('/') def v_index(): print url_for('v_contact',name='Julia',format='html') return '' @app.route('/contact/<name>') def v_contact(name):pass </name>
添加锚点 :使用_anchor关键字能够为生成的URL添加锚点。下面的示例将生成URL /contact#part2
@app.route('/') def v_index(): print url_for('v_contacts',_anchor='part2') @app.route('/contact') def v_contacts():pass
外部URL : 默认状况下,url_for()生成站内URL,能够设置关键字参数_external 为True,生成包含站点地址的外部URL。下面的示例将生成URLhttp://<x.y.z>/contacts:
@app.route('/') def v_index(): print url_for('v_contacts',_external=True) @app.route('/contact') def v_contacts():pass
更多内容如请求应答、核心机制、数据库相关、组件以及相应的示例和练习能够去这里==>http://www.hubwiz.com/course/562427361bc20c980538e26f/