Flask 项目结构

5,146 阅读3分钟

Flask 项目结构

最近要搭建一个前后端分离项目,所以在学习 flask 搭建后台,为前台提供服务。

目录结构

参考了网上的一些项目,采用了如下的结构:

├── app
│   ├── api
│   │   ├── __init__.py
│   │   ├── admin.py
│   │   └── user.py
│   ├── models          
│   │   ├── __init__.py
│   │   └── user.py
│   ├── services.py
│   │   └── __init__.py
│   ├── static
│   ├── templates
│   ├── __init__.py
│   ├── config.py
│   └── extension.py
├── manage.py
├── requirements.txt
└── README.md

app - 项目的主要功能实现:

  • api - 项目接口
  • models - 模型
  • services - 服务
  • static - 静态资源
  • template - 模板文件
  • config.py - 项目的配置
  • extension.py - 拓展配置

manage - 基于Flask-Script扩展的命令行脚本

rerequirements.txt - 该项目所依赖的第三方包

README.md - 仓库的说明

组织蓝图(Blueprint)

目前主要有两种组织方式:

  1. 按照 功能结构 组织。模板在一个文件夹中,静态文件在另外一个文件夹中,视图在第三个文件夹中。
  2. 按照 分区 组织。同一个功能的模板,静态文件,视图都在一个文件夹内。

两种组织方式的优劣并无定论,选择自己喜欢的就好。我倾向于按照分区组织,上文中的代码也是按照分区进行组织的。比如api、models、services三个模块。

将 api 注册为蓝图

由于项目使用的是前后端分离的架构方式,我采用了如下的方式进行组织:

创建一个 app/api/admin.py 文件

from flask import Blueprint
​
​
admin = Blueprint('admin', __name__)
​
​
@admin.route('/', methods=['GET'])
def index():
    return 'Hello, admin!'

创建一个 app/api/__init__.py 文件,将蓝图统一导出

from .admin import admin
​
DEFAULT_BLUEPRINT = [
    (admin, '/api/admin/'),
]
​
​
def config_blueprint(app):
    for blueprint, prefix in DEFAULT_BLUEPRINT:
        app.register_blueprint(blueprint, url_prefix=prefix)

组织扩展(Extensions)

一般推荐将所有扩展在 app/extensions.py 中进行实例化,这里我以 flask_sqlalchemy、flask_login 为例:

app/extensions.py

from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
​
db = SQLAlchemy()
login_manager = LoginManager()
​
​
# 初始化拓展
def config_extensions(app):
    db.init_app(app)
    
    login_manager.init_app(app)
​

然后在 app/__init__.py 中,进行注册。

项目配置(Config)

推荐在 app/config.py 中对整个项目进行配置:

tips:数据库一定要换成自己的

数据库一定要换成自己的

数据库一定要换成自己的

这里数据库的用户名(root)和密码(password)要换成自己的(建议在此之前先尝试连接一下数据库,避免初始化的时候报错而找不到原因)

示例:mysql://root:password@localhost:3306/database-name

root => 用户名
password => 密码
database-name => 数据库名

假设我的数据库

  • 用户名为:stillcalm
  • 密码为:123456
  • 数据库名为:user

那么我的数据库 URI :mysql://stillcalm:123456@localhost:3306/user

app/config.py

import os
​
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
​
​
# base configuration
class Config:
    SECRET_KEY = os.environ.get('KEY') or '123456'
    
    # 数据库规则
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_COMMIT_ON_TEARDOWN = True


# 开发环境
class DevelopmentConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'mysql://root:password@localhost:3306/dev-database'
​
​
# 测试环境
class TestingConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'mysql://root:password@localhost:3306/test-database'
​
​
# 生产环境
class ProductionConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'mysql://root:password@localhost:3306/product-database'# config dict
# 生成一个字典,用来根据字符串找到对应的配置类
config = {
    "development": DevelopmentConfig,
    "testing": TestingConfig,
    "production": ProductionConfig,
    "default": DevelopmentConfig
}

挂载

然后将项目配置拓展蓝图加载到 app 上

app/__init__.py

from flask import Flask
from app.api import config_blueprint
from app.extensions import config_extensions
​
​
def creat_app(DevelopmentConfig):
   
    # 实例化 app
    app = Flask(__name__)

    # 加载配置项
    app.config.from_object(config.get(config_name))
    
    # 加载拓展
    config_extensions(app)
    
    # 加载蓝图
    config_blueprint(app)
​
    return app

实例化 Flask

最后在 manage.py 中实例化(creat) Flask,并运行。

manage.py

from app import creat_app
import os
​
# 默认为开发环境,按需求修改
config_name = 'development'
​
app = creat_app(config_name)
​
if __name__ == '__main__':
    app.run()
​

总结

├── app
│   ├── api              // 接口
│   │   ├── __init__.py  // 在这里对蓝图统一导出
│   │   ├── admin.py
│   │   └── user.py
│   ├── models           // 数据库模型
│   │   ├── __init__.py
│   │   └── user.py
│   ├── services.py      // 服务可以在这里写
│   │   └── __init__.py
│   ├── static
│   ├── templates
│   ├── __init__.py 
│   ├── config.py       // 项目配置项
│   └── extension.py    // 拓展实例化
├── manage.py           // 在这里实例化 flask
├── requirements.txt    // 拓展版本管理文件
└── README.md

蓝图在 api/__init__.py 组织,拓展则在 extension.py 实例化,统一在 app/__init__.py 注册到 app 上。

最后 app 在 manage.py 中实例化。

觉得有用的话,点个赞再走吧😊

参考文章:Flask项目结构