Flask项目结构 #
一、项目结构概述 #
1.1 为什么需要良好的项目结构 #
| 优势 | 说明 |
|---|---|
| 可维护性 | 代码组织清晰,便于维护 |
| 可扩展性 | 易于添加新功能 |
| 可测试性 | 便于编写单元测试 |
| 团队协作 | 规范的结构便于团队开发 |
| 代码复用 | 模块化设计提高复用性 |
1.2 结构选择原则 #
- 小型项目:简单结构,快速开发
- 中型项目:模块化结构,便于扩展
- 大型项目:完整的分层架构,团队协作
二、小型项目结构 #
2.1 单文件结构 #
适用于学习和小型项目:
text
myapp/
├── venv/
├── app.py # 主应用文件
├── templates/ # 模板目录
│ └── index.html
├── static/ # 静态文件目录
│ ├── css/
│ │ └── style.css
│ └── js/
│ └── main.js
├── requirements.txt
└── .env
python
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
2.2 简单多文件结构 #
text
myapp/
├── venv/
├── app.py # 应用入口
├── models.py # 数据模型
├── views.py # 视图函数
├── forms.py # 表单类
├── templates/
│ ├── base.html
│ └── index.html
├── static/
│ ├── css/
│ └── js/
├── requirements.txt
└── .env
python
from flask import Flask
from views import *
app = Flask(__name__)
if __name__ == '__main__':
app.run(debug=True)
python
from app import app
from flask import render_template
@app.route('/')
def index():
return render_template('index.html')
@app.route('/about')
def about():
return render_template('about.html')
三、中型项目结构 #
3.1 包结构 #
推荐的中型项目结构:
text
myapp/
├── venv/
├── app/
│ ├── __init__.py # 创建Flask应用
│ ├── models.py # 数据模型
│ ├── views.py # 视图函数
│ ├── forms.py # 表单类
│ ├── templates/ # 模板目录
│ │ ├── base.html
│ │ ├── index.html
│ │ └── auth/
│ │ ├── login.html
│ │ └── register.html
│ └── static/ # 静态文件
│ ├── css/
│ ├── js/
│ └── images/
├── migrations/ # 数据库迁移文件
├── tests/ # 测试文件
│ ├── __init__.py
│ ├── test_models.py
│ └── test_views.py
├── config.py # 配置文件
├── requirements.txt
├── run.py # 启动脚本
└── .env
3.2 文件说明 #
app/init.py:
python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
db = SQLAlchemy()
login_manager = LoginManager()
def create_app(config_name='default'):
app = Flask(__name__)
# 加载配置
from config import config
app.config.from_object(config[config_name])
# 初始化扩展
db.init_app(app)
login_manager.init_app(app)
# 注册蓝图
from app.views import main
app.register_blueprint(main)
return app
python
import os
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key')
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'sqlite:///app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
class DevelopmentConfig(Config):
DEBUG = True
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
class ProductionConfig(Config):
DEBUG = False
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
python
import os
from app import create_app
app = create_app(os.getenv('FLASK_ENV', 'development'))
if __name__ == '__main__':
app.run()
app/views.py:
python
from flask import Blueprint, render_template
main = Blueprint('main', __name__)
@main.route('/')
def index():
return render_template('index.html')
@main.route('/about')
def about():
return render_template('about.html')
四、大型项目结构 #
4.1 完整模块化结构 #
text
myapp/
├── venv/
├── app/
│ ├── __init__.py
│ ├── models/
│ │ ├── __init__.py
│ │ ├── user.py
│ │ ├── post.py
│ │ └── comment.py
│ ├── auth/ # 认证模块
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ ├── forms.py
│ │ └── templates/
│ │ ├── login.html
│ │ └── register.html
│ ├── main/ # 主模块
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ ├── forms.py
│ │ └── templates/
│ │ ├── index.html
│ │ └── about.html
│ ├── api/ # API模块
│ │ ├── __init__.py
│ │ ├── users.py
│ │ └── posts.py
│ ├── static/
│ │ ├── css/
│ │ ├── js/
│ │ └── images/
│ ├── templates/
│ │ ├── base.html
│ │ └── macros/
│ │ └── forms.html
│ └── utils/
│ ├── __init__.py
│ ├── decorators.py
│ └── validators.py
├── migrations/
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_models/
│ │ ├── test_user.py
│ │ └── test_post.py
│ └── test_routes/
│ ├── test_auth.py
│ └── test_main.py
├── config.py
├── requirements.txt
├── run.py
├── .env
├── .flaskenv
└── README.md
4.2 模块说明 #
app/init.py:
python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_mail import Mail
from flask_migrate import Migrate
db = SQLAlchemy()
login_manager = LoginManager()
mail = Mail()
migrate = Migrate()
def create_app(config_name='default'):
app = Flask(__name__)
from config import config
app.config.from_object(config[config_name])
# 初始化扩展
db.init_app(app)
login_manager.init_app(app)
mail.init_app(app)
migrate.init_app(app, db)
# 注册蓝图
from app.auth import auth as auth_blueprint
from app.main import main as main_blueprint
from app.api import api as api_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth')
app.register_blueprint(main_blueprint)
app.register_blueprint(api_blueprint, url_prefix='/api')
return app
app/auth/init.py:
python
from flask import Blueprint
auth = Blueprint('auth', __name__)
from . import routes
app/auth/routes.py:
python
from flask import render_template, redirect, url_for, flash
from flask_login import login_user, logout_user
from . import auth
from .forms import LoginForm, RegistrationForm
from app.models.user import User
from app import db
@auth.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and user.verify_password(form.password.data):
login_user(user)
return redirect(url_for('main.index'))
flash('Invalid email or password.')
return render_template('auth/login.html', form=form)
@auth.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User(
email=form.email.data,
username=form.username.data,
password=form.password.data
)
db.session.add(user)
db.session.commit()
flash('Registration successful!')
return redirect(url_for('auth.login'))
return render_template('auth/register.html', form=form)
@auth.route('/logout')
def logout():
logout_user()
return redirect(url_for('main.index'))
app/main/init.py:
python
from flask import Blueprint
main = Blueprint('main', __name__)
from . import routes
app/main/routes.py:
python
from flask import render_template
from . import main
@main.route('/')
def index():
return render_template('index.html')
@main.route('/about')
def about():
return render_template('about.html')
app/api/init.py:
python
from flask import Blueprint
api = Blueprint('api', __name__)
from . import users, posts
app/api/users.py:
python
from flask import jsonify, request
from . import api
from app.models.user import User
@api.route('/users', methods=['GET'])
def get_users():
users = User.query.all()
return jsonify([u.to_dict() for u in users])
@api.route('/users/<int:id>', methods=['GET'])
def get_user(id):
user = User.query.get_or_404(id)
return jsonify(user.to_dict())
五、蓝图详解 #
5.1 什么是蓝图 #
蓝图是Flask中组织代码的方式,类似于Django中的应用。它允许你将相关的视图、模板和静态文件组织在一起。
5.2 创建蓝图 #
python
from flask import Blueprint
# 创建蓝图
# 参数:蓝图名称、模块名、url前缀(可选)
auth = Blueprint('auth', __name__, url_prefix='/auth')
# 定义路由
@auth.route('/login')
def login():
return '登录页面'
@auth.route('/register')
def register():
return '注册页面'
5.3 注册蓝图 #
python
from flask import Flask
from auth import auth
app = Flask(__name__)
# 注册蓝图
app.register_blueprint(auth)
# 注册时指定url前缀
app.register_blueprint(auth, url_prefix='/user')
5.4 蓝图模板 #
蓝图可以有自己的模板目录:
text
app/
├── auth/
│ ├── __init__.py
│ ├── routes.py
│ └── templates/
│ └── auth/
│ ├── login.html
│ └── register.html
└── templates/
└── base.html
在蓝图中使用模板:
python
@auth.route('/login')
def login():
return render_template('auth/login.html')
5.5 蓝图静态文件 #
python
# 创建带有静态文件的蓝图
admin = Blueprint(
'admin',
__name__,
static_folder='static',
static_url_path='/admin/static'
)
六、配置管理 #
6.1 配置类 #
python
import os
from datetime import timedelta
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard-to-guess-string'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///app.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
# Session配置
PERMANENT_SESSION_LIFETIME = timedelta(hours=1)
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
# 邮件配置
MAIL_SERVER = os.environ.get('MAIL_SERVER')
MAIL_PORT = int(os.environ.get('MAIL_PORT') or 25)
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS') is not None
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
class DevelopmentConfig(Config):
DEBUG = True
SESSION_COOKIE_SECURE = False
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
WTF_CSRF_ENABLED = False
class ProductionConfig(Config):
DEBUG = False
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
6.2 使用配置 #
python
from flask import Flask
from config import config
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
return app
app = create_app('development')
七、工厂模式 #
7.1 什么是工厂模式 #
工厂模式是一种创建对象的设计模式,在Flask中用于延迟创建应用实例,便于测试和配置切换。
7.2 实现工厂模式 #
python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app(config_name='default'):
app = Flask(__name__)
# 加载配置
from config import config
app.config.from_object(config[config_name])
# 初始化扩展
db.init_app(app)
# 注册蓝图
from app.main import main
app.register_blueprint(main)
# 创建数据库表
with app.app_context():
db.create_all()
return app
7.3 工厂模式的优势 #
| 优势 | 说明 |
|---|---|
| 多实例 | 可以创建多个应用实例 |
| 测试友好 | 每个测试使用独立配置 |
| 配置灵活 | 根据环境选择配置 |
| 延迟初始化 | 避免循环导入问题 |
八、最佳实践 #
8.1 目录命名规范 #
| 目录/文件 | 说明 |
|---|---|
| app/ | 应用主目录 |
| models/ | 数据模型 |
| views/ 或 routes/ | 视图函数 |
| forms/ | 表单类 |
| templates/ | 模板文件 |
| static/ | 静态文件 |
| tests/ | 测试文件 |
| migrations/ | 数据库迁移 |
8.2 文件命名规范 #
| 文件 | 说明 |
|---|---|
| init.py | 包初始化 |
| models.py | 数据模型 |
| views.py / routes.py | 视图函数 |
| forms.py | 表单类 |
| config.py | 配置文件 |
| run.py | 启动脚本 |
8.3 代码组织建议 #
- 模型与视图分离:将模型定义放在models.py,视图函数放在views.py
- 使用蓝图:按功能模块组织代码
- 配置分离:使用配置类管理不同环境配置
- 使用工厂模式:便于测试和多环境部署
九、总结 #
9.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 结构选择 | 根据项目规模选择合适结构 |
| 蓝图使用 | 模块化组织代码 |
| 配置管理 | 使用配置类和环境变量 |
| 工厂模式 | 延迟创建应用实例 |
9.2 下一步 #
现在你已经了解了Flask项目结构,接下来让我们学习 路由基础,深入了解Flask的路由系统!
最后更新:2026-03-28