入门
https://github.com/pallets/flask
https://flask.palletsprojects.com/
Hello Flask!
1 2 3 4 5 6 7 |
|
动态 URL
可以在 URL 规则中添加变量部分,使用 "<变量名>" 的形式表示。Flask 处理请求时会把变量传入视图函数,所以我们可以添加参数获取这个变量值
1 2 3 |
|
因为 URL 中可以包含变量,所以我们将传入 app.route() 的字符串称为 URL 规则,而不是 URL。Flask 会解析请求并把请求的 URL 与视图函数的 URL 规则进行匹配。比如,这个 greet 视图的 URL 规则为 /greet/<name>
,那么类似 /greet/foo
、/greet/bar
的请求都会触发这个视图函数
这个视图返回的响应会随着请求 URL 中的 name 变量而变化。假设程序运行在 http://helloflask.com
上,当我们在浏览器里访问 http://helloflask.com/greet/Grey
时,可以看到浏览器上显示 "Hello, Grey!"
当 URL 规则中包含变量时,如果用户访问的 URL 中没有添加变量,比如 /greet
,那么 Flask 在匹配失败后会返回一个 404 错误响应。一个很常见的行为是在 app.route() 装饰器里使用 defaults 参数设置 URL 变量的默认值,这个参数接收字典作为输入,存储 URL 变量和默认值的映射。在下面的代码中,我们为 greet 视图新添加了一个 app.route() 装饰器,为 /greet
设置了默认的 name 值
1 2 3 4 |
|
这时如果访问 /greet
,那么变量 name 会使用默认值 Programmer,视图函数返回 <h1>Hello, Programmer!</h1>
。上面的用法实际效果等同于
1 2 3 4 |
|
URL 与端点
在 Web 程序中,URL 无处不在。如果程序中的 URL 都是以硬编码的方式写出,那么将会大大降低代码的易用性。比如,当你修改了某个路由的 URL 规则,那么程序里对应的 URL 都要一个一个进行修改。更好的解决办法是使用 Flask 提供的 url_for() 函数获取 URL,当路由中定义的 URL 规则被修改时,这个函数总会返回正确的 URL
调用 url_for() 函数时,第一个参数为端点(endpoint)值。在 Flask 中,端点用来标记一个视图函数以及对应的 URL 规则。端点的默认值为视图函数的名称。
比如,下面的视图函数
1 2 3 |
|
这个路由的端点即视图函数的名称 index,调用 url_for('index') 即可获取对应的 URL,即 "/"
如果 URL 含有动态部分,那么我们需要在 url_for() 函数里传入相应的参数,以下面的视图函数为例
1 2 3 |
|
这时使用url_for('greet', name='Jack')
得到的 URL 为 "/hello/Jack"
我们使用 url_for() 函数生成的 URL 是相对 URL(即内部 URL),即 URL 中的 path 部分,比如 "/hello",不包含根 URL。相对 URL 只能在程序内部使用。如果你想要生成供外部使用的绝对 URL,可以在使用 url_for() 函数时,将 _external
参数设为 True,这会生成完整的 URL,比如 http://helloflask.com/hello
,在本地运行程序时则会获得 http://localhost:5000/hello
Flask 命令
除了 Flask 内置的 flask run 等命令,我们也可以自定义命令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
模板与静态文件
一个完整的网站当然不能只返回用户一句 “Hello, World!”,我们需要模板(template) 和静态文件(static file)来生成更加丰富的网页。模板即包含程序页面的 HTML 文件,静态文件则是需要在 HTML 文件中加载的 CSS 和 JavaScript 文件,以及图片、字体文件等资源文件。默认情况下,模板文件存放在项目根目录中的 templates 文件夹中,静态文件存放在 static 文件夹下,这两个文件夹需要和包含程序实例的模块处于同一个目录下,对应的项目结构示例如下所示:
1 2 3 4 |
|
在开发 Flask 程序时,使用 CSS 框架和 JavaScript 库时很常见的需求,而且有很多扩展都提供了对 CSS 框架和 JavaScript 库的集成功能。
使用这些扩展时都需要加载对应的 CSS 和 JavaScript 文件,通常这些扩展都会提供一些可以在 HTML 模板中使用的加载方法/函数,使用这些方法即可渲染出对应的 link 标签和 script 标签。
这些方法一般会直接从 CDN 加载资源,有写提供了手动传入资源 URL 的功能,有些甚至提供了内置的本地资源
建议在开发环境下使用本地资源,这样可以提高加载速度。
最好自己下载到 static 目录下,统一管理,出于方便的考虑也可以使用扩展内置的本地资源。
在过渡到生产环境时,自己手动管理所有本地资源或自己设置 CDN,避免使用扩展内置的资源。
这个建议主要基于下面这些考虑因素:
- 鉴于国内的网络状况,扩展默认使用的国外 CDN 可能会无法访问,或访问过慢
- 不同扩展内置的加载方法可能会加载重复的依赖资源,比如 jQuery
- 在生产环境下,将静态文件集中在一起更方便管理
- 扩展内置的资源可能会出现版本过旧的情况
注:
CDN 指分布式服务器系统。服务商把你需要的资源存储在分布于不同地理位置的多个服务器,它会根据用户的地理位置来就近分配服务器提供服务(服务器越近,资源传送就越快)。
使用 CDN 服务可以加快网页资源的加载速度,从而优化用户体验。
对于开源的 CSS 和 JavaScript 库,CDN 提供商通常会免费提供服务
Flask 与 MVC 架构
你也许会困惑为什么用来处理请求并生成响应的函数被称为“视图函数(view function)”,其实这个命名并不合理。
在 Flask 中,这个命名的约定来自 Werkzeug,而 Werkzeug 中 URL 匹配的实现主要参考了 Routes(一个 URL 匹配库),再往前追溯,Routes 的实现又参考了 Ruby on Rails(http://rubyonrails.org/)。
在 Ruby on Rails 中,术语 views 用来表示 MVC(Model-View-Controller,模型-视图-控制器)架构中的 View
MVC 架构最初是用来设计桌面程序的,后来也被用于 Web 程序,应用了这种架构的 Web 框架有 Django、Ruby on Rails 等。
在 MVC 架构中,程序被分为三个组件: 数据处理(Model)、用户界面(View)、交互逻辑(Controller)。
如果套用 MVC 架构的内容,那么 Flask 中视图函数的名称其实并不严谨,使用控制器函数(Controller Function)似乎更合适些,虽然它也附带处理用户界面。
严格来说,Flask 并不是 MVC 架构的框架,因为它没有内置数据模型支持。