定义
先让大家明确一些术语,方便后面的讨论。仓库/版本库 - 应用程序所在的基础文件夹。习惯上指笨笨控制系统。在文章中提到时,指的是项目的根目录。
包 - 指应用代码的一个Python包。
模块 - 一个模块指能被其他的Python文件导入的一个Python文件。一个包基本上是打包在一起的多个模块。
常用扩展(Extensions)
Flask作为微框架(microframework),在开发过程中会经常使用各种扩展包。以下是一些常用扩展包的简介。Flask-SQLAlchemy - 封装了SQLAlchemy,提供ORM
Flask-Migrate - 处理SQLAlchemy数据库的迁移(migrations)
Flask-Script - 支持在Flask里编写额外的脚本
Flask-Bootstrap - 封装了Bootstrap框架
Flask-Login - 提供账号session管理
Flask-WTF - 封装了WTForms,提供表单功能
Flask-RESTful - 提供快速构建RESTAPIs的能力
目录结构
一般Flask的项目结构如下:
├── README.md
├── app
│ ├── __init__.py
│ ├── api
│ │ ├── __init__.py
│ │ └── views.py
│ ├── auth
│ │ ├── __init__.py
│ │ ├── forms.py
│ │ ├── templates
│ │ │ └── auth.html
│ │ └── views.py
│ ├── extensions.py
│ ├── forms.py
│ ├── main
│ │ ├── __init__.py
│ │ ├── errors.py
│ │ ├── models.py
│ │ ├── templates
│ │ │ └── index.html
│ │ └── views.py
│ └── models.py
├── config.py
├── fabfile.py
├── manage.py
├── migrations
├── requirements
│ ├── common.txt
│ ├── dev.txt
│ └── prod.txt
└── unit_testsREADME.md - 仓库的说明,比如该项目的介绍等
app - 项目的主要功能实现
config.py - 项目的配置
fabfile.py - 使用Fabric3完成项目发布工作的脚本
manage.py - 基于Flask-Script扩展的命令行脚本
requirements - 该项目所依赖的第三方包
unit_tests - 单元测试相关代码
组织蓝图
目前主要有两种组织方式:按照 功能结构 组织。模板在一个文件夹中,静态文件在另外一个文件夹中,视图在第三个文件夹中。
按照 分区 组织。同一个功能的模板,静态文件,视图都在一个文件夹内。
两种组织方式的优劣并无定论,选择自己喜欢的就好。笔者倾向于按照分区组织,上文中的代码也是按照分区进行组织的。比如api、auth、main三个模块。
将RESTful-api注册为蓝图
当你使用前后端分离的架构方式时,可考虑如下的方式进行组织(以上文的api文件夹为例):
api/views.py
# coding: utf-8
from flask_restful import Api, Resource
api = Api()
@api.resource('/tmp_api')
class TmpApiResource(Resource):
def get(self):
pass
api/__init__.py
# coding: utf-8
from flask import Blueprint
api_bp = Blueprint('api_bp', __name__)
from .views import api
api.init_app(api_bp)
最后将api_bp注册到app上,跟其他蓝图保持一致。
组织扩展(Extensions)
一般推荐将所有扩展在app/extensions.py中进行实例化,如以下代码:
app/extensions.py
# coding: utf-8
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
bootstrap = Bootstrap()
db = SQLAlchemy()
login_manager = LoginManager()
login_manager.login_view = 'auth_bp.login'
然后在实例化Flask时,进行绑定:
app/__init__.py
# coding: utf-8
import os
from flask import Flask
from config import config
from app.extensions import bootstrap, db, login_manager
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
bootstrap.init_app(app)
db.init_app(app)
login_manager.init_app(app)
# register blueprint
from .main import main_bp
app.register_blueprint(main_bp)
from .auth import auth_bp as auth_blueprint
app.register_blueprint(auth_blueprint)
from .api import api_bp as api_blueprint
app.register_blueprint(api_blueprint, url_prefix='/api')
return app