Flask开发大型项目的结构
项目结构
- app:所有的项目功能,核心代码,如果要给项目添加功能就更方便
- auth:用户认证模块
- todo:任务清单操作模块
- view.py:视图函数,路由处理
- models.py:数据库处理模块
- email.py:邮箱处理模块
- error:异常处理模块
- requirements.txt 列出了所有依赖包,便于在其他电脑中重新生成相同的虚拟环境;
pip freeze > requirements.txt # 冻结当前第三方模块有哪些重定向到requirements.txt
pip install -r requirements.txt # 递归安装requirements.txt 里边的文件
- config.py 存储配置;
- manage.py 用于启动程序以及其他的程序任务,以及通过命令行来管理我们的项目,自定义一些命令,flask-script
- tests:测试目录
项目配置文件选项
官方文档
程序经常需要设定多个配置。一般分为开发、测试和生产环境, 它们使用不同的数据库,不会彼此影响。
该项目的配置信息主要包括数据库的配置和邮箱的配置,
项目开始使用的是sqllite数据库
app.config[‘SQLALCHEMY_DATABASE_URI’] =
‘sqlite:///’ + os.path.join(basedir, ‘data.sqlite’)
最后将项目部署到云服务器时使用的是mysql数据库
class Config()
# 首先设置配置环境的基类,其他的开发、测试、生产环境都要继承这个基类
# 从环境变量中获取SECRET_KEY如果没有则使用自己设置的
# 尤其是涉及(flask-wtf)登录注册里面提交敏感信息时,一定要加
# 数据提交到session中时必须要有SECRET_KEY,否则回报错
SECRET_KEY = os.environ.get('SECRET_KEY') or 'westos secret key'
# 设置数据库自动提交,每次请求结束都会提交数据库的变动
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
# sqlchemy将会追踪对象的修改并且发送信号
SQLALCHEMY_TRACK_MODIFICATIONS = True
FLASKY_MAIL_SUBJECT_PREFIX = '[西部开源]'
# 设置邮件发送方的邮箱地址
FLASKY_MAIL_SENDER = '976131979@qq.com'
# 加载一些初始化文件,后续添加
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
# 开发环境
# 启用了调试支持,服务器会在代码修改后自动重新载入,并在发生错误时提供一个相当有用的调试器。
DEBUG = True
MAIL_SERVER = 'smtp.qq.com' # 指定邮件服务器
MAIL_PORT = 587 # 邮件服务器的端口
MAIL_USE_SSL = True # 是否开启ssl加密传输
MAIL_USERNAME = '976131979@qq.com' # 设置发送方邮箱地址
MAIL_PASSWORD = # 不是登陆密码,而是邮箱开启stmp服务的授权码
# 数据库存放的地址,以及要连接什么数据库
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
class TestingConfig(Config):
"""
测试环境的配置信息
"""
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'data-test.sqlite')
class ProductionConfig(Config):
# 注意:生产环境中必须要把DEBUG关闭
"""
生产环境的配置信息
"""
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir,
'data.sqlite')
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
程序工厂函数
- 为什么需要程序工厂函数?
在单个文件中开发程序很方便,但却有个很大的缺点,因为程序在全局作用域中创建,所以无法动态修改配置。运行脚本时,程序实例已经创建,再修改配置为时已晚。这一点对单元测试尤其重要,因为有时为了提高测试覆盖度,必须在不同的配置环境中运行程序。
这个问题的解决方法是延迟创建程序实例,把创建过程移到可显式调用的工厂函数中。这种方法不仅可以给脚本留出配置程序的时间,还能够创建多个程序实例。 - 如何实现程序工厂函数?
创建扩展类时不向构造函数传入参数, 在之前创建的扩展对象上调用 init_app() 可以完成初始化过程。
"""
程序工厂函数的目的: 延迟创建Flask应用, 应用场景如下:
1). 测试。可以使用多个应用程序的实例,为每个实例分配分配不同的配置, 从而测试每一种不同的情况。
2). 多个实例。要同时运行同一个应用的不同版本,可以在你的Web服务器中配置多个实例并分配不同的配置.
"""
from flask import Flask
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_mail import Mail
from flask_login import LoginManager
import pymysql
pymysql.install_as_MySQLdb()
from config import config
bootstrap = Bootstrap()
db = SQLAlchemy()
mail = Mail()
login_manager = LoginManager()
# session_protection 属性提供不同的安全等级防止用户会话遭篡改。
login_manager.session_protection = 'strong'
# login_view 属性设置登录页面的端点。
login_manager.login_view = 'auth.login'
def create_app(config_name='development'):
"""
默认创建开发环境的app对象
"""
app = Flask(__name__)
"""
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
"""
# 加载config类中的配置
app.config.from_object(config[config_name])
# config[config_name].init_app(app)
# 初始化app,将app与bootstrap对象绑定在一起
bootstrap.init_app(app)
mail.init_app(app)
db.init_app(app)
login_manager.init_app(app)
蓝图:组件化开发
-
什么是蓝图?
Flask蓝图提供了模块化管理程序路由的功能,使程序结构清晰、简单易懂。
假如说我们要为某所学校的每个人建立一份档案,一个很自然的优化方式就是这些档案如果能分类管理,就是说假如分为老师、学生、后勤人员等类别,那么后续查找和管理这些档案就方便清晰许多。Flask的蓝图就提供了类似“分类”的功能。 -
为什么使用蓝图?
- 将不同的功能模块化
- 构建大型应用
- 优化项目结构
- 增强可读性,易于维护
-
应用蓝图三部曲
1、蓝图的创建: app/auth/init.py
#'auth’是蓝图的名称
#__name__是蓝图所在路径
auth =Blueprint(‘auth’,name)
#把路由和错误处理程序与蓝本关联, 一定要写在最后, 防止循环导入依赖;
from . import views # 注意一定要从当前导入views,因为程序加载时只会加载init文件
2、蓝图对象上注册路由,指定静态文件夹,注册模版过滤器: app/auth/views.py
@auth.route(’/’)
def auth_home():
return ‘auth_home’
3、注册蓝图对象 app/init.py
#url_prefix: 指定访问该蓝图中定义的视图函数时需要添加的前缀, 没有指定则不加;
app.register_blueprint(auth,url_prefix=’/auth’)
- 访问网址 http://127.0.0.1:5000/auth/ 可以查看到 auth_home 的内容。
启动脚本 manage.py
程序运行的入口,主要用来创建app,并且配置使程序能够在命令行运行。
Flask-Script用来生成shell命令;为在Flask里编写额外的脚本提供了支持。
- 这包括运行一个开发服务器,一个定制的Python命令行,用于执行初始化数据库、定时任务和其他属于web应用之外的命令行任务的脚本。
- Flask-Script和Flask本身的工作方式类似。只需要定义和添加能从命令行中被Manager实例调用的命令即可。
添加自定义命令的3种方式:
参考网站
- 使用command装饰器
- 定义Command的子类;
- 使用option装饰器
from app import create_app, db
from flask_script import Manager, Shell
from flask_migrate import Migrate, MigrateCommand
from app.models import Role, User
app = create_app()
manager = Manager(app)
# 将数据库迁移插件与数据库db和app关联
migrate = Migrate(app, db)
@manager.command
def tests():
"""
执行Flask项目的测试用例
"""
import unittest
# 发现所有的测试用例(TestCase)绑定成一个测试集合(TestSuite), TestLoader
tests = unittest.TestLoader().discover('tests')
# verbosity是测试结果的信息复杂度,有0、1、2 三个值
unittest.TextTestRunner(verbosity=2).run(tests)
def make_shell_context():
return dict(app=app, db=db, Role=Role, User=User)
if __name__ == '__main__':
# app = create_app()
# # 0.0.0.0: 0代表任意,
# # 绑定本机的所有IP, http://IP:8888
# app.run(host='0.0.0.0', port='8888')
# 初始化 Flask-Script、Flask-Migrate 和为 Python shell 定义的上下文。
# 通过上下文的方式将命令加入到shell命令行中
manager.add_command("shell", Shell(make_context=make_shell_context))
# 使用Flask-script集成的数据库操作
manager.add_command("db", MigrateCommand)
manager.run()
项目与github
GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名GitHub。
由于一些原因国内的gitbub网速限值,导致使用起来非常慢,国内也开发了一款git托管平台码云(gitee)
使用方法与github一模一样
1、首先在码云上创建一个远程仓库Todolist
2、初始化git目录
git init
在当前目录先出现一个.git的隐藏文件
3、将所有项目文件添加到暂存区
git add *
4、提交到本地仓库
git commit -m “Flask任务清单管理系统(一): 大型项目结构化管理”
5、添加一个新的远程仓库, 第一次需要, 后面的不需要添加.
git remote add origin https://gitee.com/tcyw/TodoList.git
6、上传项目至远程仓库Github
git push origin master
然后输入用户名和密码就可以上传了
Git常用命令流程图:
Git命令快速查找手册