原文地址:[Python web 开发实战]
即插视图
即插视图的灵感来自 Django 的基于类而不是函数的通用视图方式,这样的视图就可以支持继承了。视图类型有两种类型。
标准视图
标准视图需要继承 flask.views.View, 必须实现 dispatch_request。看一个例子:app_view.py
1 | from flask import Flask, request, render_template |
模板存放在 ~/web_develop/templates 下,使用 __name__
来获取模板目录,template_folder
是相对于 app.py 文件的,需要设置成 ‘../../templates’ 才能找到正确的模板目录。
基于调度方法的视图
flask.views.MethodView 对于每个 HTTP 方法执行不同的函数(映射到对应方法的小写的同名方法上),这对 RESTful API 由其有用,看一个例子:app_api.py
1 | from flask import Flask, jsonify |
通过装饰 as_view 的返回值来实现对于视图的装饰功能,常用于权限的检查,登录验证等:
1 | def user_required(f): |
从 Flask 0.8 开始,还可以通过继承 MethodView 的类中添加 decorators 属性来实现对视图的装饰:
1 | class UserAPI(MethodView): |
蓝图
蓝图实现了应用的模块化,使用蓝图让应用层次清晰,开发者可以更容易的开发和维护项目。蓝图通常作用于相同的 URL 前缀,比如 /user:id, /user/profile 这样的地址,都以 /user 开头,那么他们就可以放在一个模块中。看一个最简单的示例:user.py
1 | from flask import Blueprint |
每个模块都会暴露一个全局变量 bp,再看主程序 (app_bp.py):app_bp.py
1 | from flask import Flask |
使用 register_blueprint 注册模块,如果想去掉模块,只需要去掉对应的注册语句即可。
子域名
现在许多 SaaS 应用为用户提供一个子域名来访问,可以借助 subdomain 来实现同样的功能:app_subdomain.py
1 | from flask import Flask, g |
在 /etc/hosts 中添加域名绑定:
1 | 127.0.0.1 a.example.com b.example.com |
现在验证它:
1 | htto http://b.example.com:9000 --print b # b 表示只输出响应的主体 |
命令行接口
在 Flask 0.11 之前,启动的应用的端口,主机地址以及是否开启 DEBUG 模式,都需要在代码中明确指定,一个比较好的方式是使用第三方扩展 Flask-Script 管理。从 Flask 0.11 开始,Flask 集成了 Click,现在可以直接在命令行执行 flask 命令启动 Flask 应用了:
1 | export FLASK_APP=chapter3/section1/hello.py |
这种命令行启动的方式要灵活得多,命令 flask 还支持 shell 子命令:
1 | % flask shell |
新的方案甚至能够替换 Flask-Script。现在我们基于 flask.cli 模块添加两个子命令:app_cli.py
- 第一个子命令 initdb,用来初始化数据库,这里没有实际的逻辑,只是为了演示 click 的使用方法:
1
2
3
4
5
6
7
8
9import click
from flask import Flask
app = Flask(__name__)
def initdb():
click.echo('Init the db')
先指定 FLASK_APP 变量
1 | export FLASK_APP=chapter3/section1/app_cli.py |
现在就可以使用 initdb 了:
1 | > flask initdb |
再复杂些,实现一个叫做 new_shell 的子命令,它使用 Python 环境(除非没有安装 IPython或者强制要求使用默认的交互环境):
1 | import click |
其中,app.cli.command 用来指定子命令的名字和帮助信息,click.option 给子命令添加参数,由于 new_shell 需要使用 app 这个上下文,所以需要添加 with_appcontext 这个装饰器。