Flask大型应用结构

项目结构

一般结构有四个顶级文件夹:

  • Flask应用一般保存在名为app的包中;
  • 数据库迁移脚本在migrations文件夹中;
  • 单元测试在tests包中;
  • python虚拟环境在venv中。

除此之外还有config.py存储配置。

requirements.txt列出所有依赖包。

flasky.py作为主脚本,定义Flask应用实例,同时还有一些辅助管理应用的任务。

应用包

应用包存放应用的所有代码、模板和静态文件。templates和static现在在app包中。数据库模型和电子邮件支持函数也在app包中。

蓝本

蓝本和应用类似,也可以定义路由和错误处理程序。不同的是,在蓝本中定义的路由和错误处理程序处于休眠状态,直到蓝本注册到应用上之后,它才真正成为应用的一部分。下面是app/main/__init__.py的代码

1
2
3
4
5
from flask import Blueprint

main = Blueprint('main', __name__)

from . import views, errors

蓝本通过实例化一个Blueprint类对象创建。两个参数:蓝本的名称和蓝本所在的包或模块。

应用的路由保存在app/main/views.py中,错误处理程序保存在app/main/errors.py中。导入这连个模块就能把路由和错误处理程序与蓝本联系起来。因为在views和errors中也要导入main蓝本,为了避免循环导入依赖,导入views和errors要在

__init__.py的末尾。


在蓝本中编写错误处理程序稍有不同,如果使用errorhandler装饰器,那么只有蓝本中的错误才能触发处理程序。要想注册全局的错误处理程序,必须使用app_errorhandler装饰器。

1
2
3
4
5
6
from flask import render_template
from . import main

@main.app_errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404

在蓝本中编写视图函数主要有两点不同:第一,路由装饰器由蓝本提供,因此使用main.route而非app.route。第二,url_for()函数的用法不同。在蓝本中,Flask会为所有蓝本中的全部端点加上一个命名空间,这样就可以在不同的蓝本中使用相同的端点名定义视图函数,而不冲突。命名空间是蓝本的名称(Blueprint构造函数的第一个参数),而且与端点名之间以一个点号分隔。因此视图函数index()注册的端点名是main.index,其URL用url_for('main.index')获取。

在蓝本中可以省略蓝本名,例如url_for('.index')这种写法,使用当前请求的蓝本名补足端点名。这意味着,同一蓝本的重定向可以使用简写,但跨蓝本的重定向必须使用带有蓝本名的完全限定端点名。