魔方APP项目-02-服务端项目搭建,创建manage.py文件、构建全局初始化函数创建app应用对象、通过终端脚本启动项目、项目加载配置、数据库初始化、日志初始化、蓝图初始化
服务端项目搭建
新建项目目录mofangapi,并创建虚拟环境
mkvirtualenv mofang
安装开发中使用的依赖模块
pip install flask==0.12.4
pip install flask-redis
pip install flask-session
pip install flask-script
pip install flask-mysqldb
pip install flask-sqlalchemy
pip install flask-migrate
在pycharm中打开项目目录mofangapi编写manage.py启动项目的文件
一、创建 manage.py 文件
from flask import Flaskapp = Flask(__name__)@app.route('/')
def index():return 'index'if __name__ == '__main__':app.run()
manage.py中不能存放大量的开发代码, 在开发中应该体现的是一种分工精神,所以我们可以把flask中各种功能代码进行分类分文件存储.
创建项目目录结构:
项目根目录/
├── application/ # 项目主要逻辑代码保存目录
| ├── settings/ # 项目配置存储目录
│ │ ├ dev.py # 开发阶段的配置文件
│ │ ├ prod.py # 生产阶段的配置文件
| | ├ __init__.py # 项目公共配置文件
│ ├── __init__.py # 项目初始化文件
├── manage.py # 项目的终端管理脚本文件
二、构建全局初始化函数创建app应用对象
把引导整个项目启动的全局初始化代码,保存到application/__init__py
,代码:
from flask import Flaskdef init_app():"""全局初始化"""app = Flask(__name__)return app
manage.py中调用初始化函数,创建app应用对象,代码:
from application import init_appapp = init_app()@app.route('/')
def index():return 'index'if __name__ == '__main__':app.run()
三、通过终端脚本启动项目
applicatiion/__init__py
,代码:
from flask import Flask
from flask_script import Managermanager = Manager()def init_app():"""全局初始化"""# 创建app应用对象app = Flask(__name__)# 初始化终端脚本工具manager.app = appreturn manager
manage.py,代码:
from application import init_appmanage = init_app()@manage.app.route('/')
def index():return 'index'if __name__ == '__main__':manage.run()
运行项目的方式就要修改成如下:
python manage.py runserver -h0.0.0.0 -p5000
终端运行效果:
四、项目加载配置
在application/utils/config.py中准备加载配置的函数代码:
from importlib import import_module
def load_config(config_path):"""自动加载配置"""module = import_module(config_path)name = config_path.split(".")[-1]if name == "settings":return module.InitConfigelse:return module.Config
编写项目默认配置文件, application/settings/__init__.py
代码:
class InitConfig():"""项目默认初始化配置"""DEBUG = True
当然, 项目开发过程完成以后肯定会项目上线,所以针对配置文件,我们可以准备不同环境下的配置
application/settings/dev.py
,代码:
from . import InitConfig
class Config(InitConfig):"""项目开发环境下的配置"""DEBUG = True
application/settings/prod.py
,代码:
from . import InitConfig
class Config(InitConfig):"""项目运营环境下的配置"""DEBUG = False
在项目引导文件application/__init__py
中加载配置,代码:
from flask import Flask
from flask_script import Manager
from application.utils.config import load_config
manager = Manager()def init_app(config_path):"""全局初始化"""# 创建app应用对象app = Flask(__name__)# 项目根目录app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 加载配置Config = load_config(config_path)app.config.from_object(Config)# 初始化终端脚本工具manager.app = appreturn manager
在创建app对象的项目启动文件manage.py中,设置配置
from application import init_appmanage = init_app("application.settings.dev")@manage.app.route('/')
def index():return 'index'if __name__ == '__main__':manage.run()
五、数据库初始化
1.SQLAlchemy初始化
默认项目配置文件中增加配置选项,application/settings/__init__.py
,代码:
class InitConfig():"""项目默认初始化配置"""# 调试模式DEBUG = True# 数据库相关配置SQLALCHEMY_DATABASE_URI = ""# 动态追踪修改设置SQLALCHEMY_TRACK_MODIFICATIONS = False# 查询时会显示原始SQL语句SQLALCHEMY_ECHO= True
开发配置dev.py
中,配置数据库连接信息,代码:
from . import InitConfig
class Config(InitConfig):"""项目开发环境下的配置"""DEBUG = True# 数据库SQLALCHEMY_DATABASE_URI = "mysql://mofang_user:mofang@127.0.0.1:3306/mofang?charset=utf8mb4"SQLALCHEMY_ECHO = True
在mysql终端下, 创建数据库用户,命令如下:
create database mofang charset=utf8mb4;
# 针对当前数据库配置账户信息
create user mofang_user identified by 'mofang';
grant all privileges on mofang.* to 'mofang_user'@'%';
flush privileges;
在项目全局引导文件中,对数据库功能进行初始化,application/__init__.py
,代码:
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from application.utils.config import load_config# 创建终端脚本管理对象
manager = Manager()# 创建数据库链接对象
db = SQLAlchemy()def init_app(config_path):"""全局初始化"""# 创建app应用对象app = Flask(__name__)# 项目根目录app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 加载配置Config = load_config(config_path)app.config.from_object(Config)# 数据库初始化db.init_app(app)# 初始化终端脚本工具manager.app = appreturn manager
2.Redis数据库初始化
默认配置文件,application/settings/__init__py
,代码:
class InitConfig():"""项目默认初始化配置"""# 调试模式DEBUG = True# 数据库相关配置SQLALCHEMY_DATABASE_URI = ""# 动态追踪修改设置SQLALCHEMY_TRACK_MODIFICATIONS = False# 查询时会显示原始SQL语句SQLALCHEMY_ECHO= True# RedisREDIS_URL = "redis://@127.0.0.1:6379/0"
在全局引导文件中, 对redis进行初始化,applicaiton/__init__.py
,代码:
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedisfrom application.utils.config import load_config# 创建终端脚本管理对象
manager = Manager()# 创建数据库链接对象
db = SQLAlchemy()# redis链接对象
redis = FlaskRedis()def init_app(config_path):"""全局初始化"""# 创建app应用对象app = Flask(__name__)# 项目根目录app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 加载配置Config = load_config(config_path)app.config.from_object(Config)# 数据库初始化db.init_app(app)redis.init_app(app)# 初始化终端脚本工具manager.app = appreturn manager
3.Session存储到redis数据库中
因为需要单独设置一个数据库存放session,所以我们再次单独配置一个关于session加载配置的函数init_session
。
application/utils/session.py
,代码:
from redis import Redis
def init_session(app):host = app.config.get("SESSION_REDIS_HOST","127.0.0.1")port = app.config.get("SESSION_REDIS_PORT",6379)db = app.config.get("SESSION_REDIS_DB",0)print(db)app.config["SESSION_REDIS"] = Redis(host=host,port=port,db=db)
默认配置文件application/settings/__init__.py
中, 添加配置项:
class InitConfig():"""项目默认初始化配置"""# 调试模式DEBUG = True# 数据库相关配置SQLALCHEMY_DATABASE_URI = ""# 动态追踪修改设置SQLALCHEMY_TRACK_MODIFICATIONS = False# 查询时会显示原始SQL语句SQLALCHEMY_ECHO= True# RedisREDIS_URL = ""# 设置密钥,可以通过 base64.b64encode(os.urandom(48)) 来生成一个指定长度的随机字符串SECRET_KEY = "y58Rsqzmts6VCBRHes1Sf2DHdGJaGqPMi6GYpBS4CKyCdi42KLSs9TQVTauZMLMw"# session存储配置# session存储方式配置SESSION_TYPE = "redis"# 如果设置session的生命周期是否是会话期, 为True,则关闭浏览器session就失效SESSION_PERMANENT = False# 设置session_id在浏览器中的cookie有效期PERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # session 的有效期,单位是秒# 是否对发送到浏览器上session的cookie值进行加密SESSION_USE_SIGNER = True# 保存到redis的session数的名称前缀SESSION_KEY_PREFIX = "session:"# session保存数据到redis时启用的链接对象SESSION_REDIS = None # 用于连接redis的配置SESSION_REDIS_HOST = "127.0.0.1"SESSION_REDIS_PORT = 6379SESSION_REDIS_DB = 0
在本地开发配置中,设置session存储指定的redis库中,application/settings/dev.py
,代码:
from . import InitConfig
class Config(InitConfig):"""项目开发环境下的配置"""DEBUG = True# 数据库SQLALCHEMY_DATABASE_URI = "mysql://mofang_user:mofang@127.0.0.1:3306/mofang?charset=utf8mb4"SQLALCHEMY_ECHO = True# redisREDIS_URL = "redis://@127.0.0.1:6379/0"# session存储配置SESSION_REDIS_HOST = "127.0.0.1"SESSION_REDIS_PORT = 6379SESSION_REDIS_DB = 1
在项目全局引导文件application/__init__.py
中对session存储进行初始化,代码:
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Sessionfrom application.utils.config import load_config
from application.utils.session import init_session
# 创建终端脚本管理对象
manager = Manager()# 创建数据库链接对象
db = SQLAlchemy()# redis链接对象
redis = FlaskRedis()# Session存储对象
session_store = Session()def init_app(config_path):"""全局初始化"""# 创建app应用对象app = Flask(__name__)# 项目根目录app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 加载配置Config = load_config(config_path)app.config.from_object(Config)# 数据库初始化db.init_app(app)redis.init_app(app)# session存储初始化init_session(app)session_store.init_app(app)# 初始化终端脚本工具manager.app = appreturn manager
4.数据迁移初始化
项目全局引导文件application/__init__py
,代码:
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_migrate import Migrate,MigrateCommandfrom application.utils.config import load_config
from application.utils.session import init_session# 创建终端脚本管理对象
manager = Manager()# 创建数据库链接对象
db = SQLAlchemy()# redis链接对象
redis = FlaskRedis()# Session存储对象
session_store = Session()# 数据迁移实例对象
migrate = Migrate()def init_app(config_path):"""全局初始化"""# 创建app应用对象app = Flask(__name__)# 项目根目录app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 加载配置Config = load_config(config_path)app.config.from_object(Config)# 数据库初始化db.init_app(app)redis.init_app(app)# session存储初始化init_session(app)session_store.init_app(app)# 数据迁移初始化migrate.init_app(app,db)# 添加数据迁移的命令到终端脚本工具中manager.add_command('db', MigrateCommand)# 初始化终端脚本工具manager.app = appreturn manager
完成上面的项目构建步骤以后,此时目录结构如下:
项目根目录/
├── docs/ # 项目开发文档/接口等备份资料存储目录
├── logs/ # 项目日志存储目录
├── application/ # 项目主要逻辑代码保存目录
| ├── settings/ # 项目配置存储目录
│ │ ├ dev.py # 开发阶段的配置文件
│ │ ├ prod.py # 生产阶段的配置文件
| | ├ __init__.py # 项目公共配置文件
| ├── utils/ # 工具函数库/类库
│ │ ├ session.py # session相关的辅助函数
│ │ ├ config.py # 配置相关的辅助函数
│ ├── __init__.py # 项目初始化文件
└── manage.py # 项目的终端管理脚本文件
六、日志初始化
flask中没有内置的日志功能,我们在使用的时候, 一般日志如果不是核心重点,则通过由python内置的logging模块进行配置集成使用即可, 如果项目中日志发挥作用比较重要, 则一般安装部署 ELK日志分析系统.
1.日志的等级
FATAL/CRITICAL = 致命的,危险的
ERROR = 错误
WARNING = 警告
INFO = 信息
DEBUG = 调试
2.构建日志模块
把日志初始化相关的代码封装成一个函数,application/utils/logger.py
,代码:
import logging
from logging.handlers import RotatingFileHandlerclass Log():"""日志模块"""def __init__(self, app=None):if app is not None:self.init_app(app)def init_app(self,app):self.app = appreturn self.setup()def setup(self):"""安装日志功能到flask中"""# 设置日志的记录等级logging.basicConfig(level=self.app.config.get("LOG_LEVEL")) # 调试debug级# 创建日志记录器,指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限file_log_handler = RotatingFileHandler(self.app.BASE_DIR+self.app.config.get("LOG_DIR"),maxBytes=self.app.config.get("LOG_MAX_BYTES"),backupCount=self.app.config.get("LOG_BACKUP_COUNT"))# 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息formatter = logging.Formatter('%(name)s: %(levelname)s %(asctime)s %(filename)s:%(lineno)d %(message)s')# 为刚创建的日志记录器设置日志记录格式file_log_handler.setFormatter(formatter)# 为全局的日志工具对象(flaskapp使用的)添加日志记录器logging.getLogger(self.app.config.get("LOG_NAME")).addHandler(file_log_handler)# 返回日志器对象提供给业务开发logger = logging.getLogger(self.app.config.get("LOG_NAME"))return logger
application/settings/__init__.py
代码:
class InitConfig():"""项目默认初始化配置"""# 调试模式DEBUG = True# 数据库相关配置SQLALCHEMY_DATABASE_URI = ""# 动态追踪修改设置SQLALCHEMY_TRACK_MODIFICATIONS = False# 查询时会显示原始SQL语句SQLALCHEMY_ECHO= True# RedisREDIS_URL = ""# 设置密钥,可以通过 base64.b64encode(os.urandom(48)) 来生成一个指定长度的随机字符串SECRET_KEY = "y58Rsqzmts6VCBRHes1Sf2DHdGJaGqPMi6GYpBS4CKyCdi42KLSs9TQVTauZMLMw"# session存储配置# session存储方式配置SESSION_TYPE = "redis"# 如果设置session的生命周期是否是会话期, 为True,则关闭浏览器session就失效SESSION_PERMANENT = False# 设置session_id在浏览器中的cookie有效期PERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # session 的有效期,单位是秒# 是否对发送到浏览器上session的cookie值进行加密SESSION_USE_SIGNER = True# 保存到redis的session数的名称前缀SESSION_KEY_PREFIX = "session:"# session保存数据到redis时启用的链接对象SESSION_REDIS = None # 用于连接redis的配置SESSION_REDIS_HOST = "127.0.0.1"SESSION_REDIS_PORT = 6379SESSION_REDIS_DB = 1# 调整json数据转换中文的配置JSON_AS_ASCII=False# 日志相关配置LOG_LEVEL = "INFO" # 日志输出到文件中的最低等级LOG_DIR = "logs/0.log" # 日志存储目录LOG_MAX_BYTES = 300 * 1024 * 1024 # 单个日志文件的存储上限[单位: b]LOG_BACKUP_COUNT = 20 # 日志文件的最大备份数量LOG_NAME = "flask" # 日志器的名字
开发环境配置文件dev.py
中配置具体的日志相关信息,代码:
from . import InitConfig
class Config(InitConfig):"""项目开发环境下的配置"""DEBUG = True# 数据库SQLALCHEMY_DATABASE_URI = "mysql://mofang_user:mofang@127.0.0.1:3306/mofang?charset=utf8mb4"SQLALCHEMY_ECHO = True# redisREDIS_URL = "redis://@127.0.0.1:6379/0"# session存储配置SESSION_REDIS_HOST = "127.0.0.1"SESSION_REDIS_PORT = 6379SESSION_REDIS_DB = 1# 日志配置LOG_LEVEL = "DEBUG" # 日志输出到文件中的最低等级LOG_DIR = "/logs/mofang.log" # 日志存储目录LOG_MAX_BYTES = 300 * 1024 * 1024 # 单个日志文件的存储上限[单位: b]LOG_BACKPU_COUNT = 20 # 日志文件的最大备份数量LOG_NAME = "mofang" # 日志器名称
在 application/__init__.py
文件中的init_app
方法中调用日志初始化。
import os,loggingfrom flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_migrate import Migrate,MigrateCommandfrom application.utils.config import load_config
from application.utils.session import init_session
from application.utils.logger import Log
# 创建终端脚本管理对象
manager = Manager()# 创建数据库链接对象
db = SQLAlchemy()# redis链接对象
redis = FlaskRedis()# Session存储对象
session_store = Session()# 数据迁移实例对象
migrate = Migrate()# 日志对象
log = Log()def init_app(config_path):"""全局初始化"""# 创建app应用对象app = Flask(__name__)app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 加载配置Config = load_config(config_path)app.config.from_object(Config)# 数据库初始化db.init_app(app)redis.init_app(app)# session存储初始化init_session(app)session_store.init_app(app)# 数据迁移初始化migrate.init_app(app,db)# 添加数据迁移的命令到终端脚本工具中manager.add_command('db', MigrateCommand)# 日志初始化app.log = log.init_app(app)# 初始化终端脚本工具manager.app = appreturn manager
新增日志以后的项目目录结构
.
├── application
│ ├── __init__.py
│ ├── settings
│ │ ├── dev.py
│ │ ├── __init__.py
│ │ ├── prod.py
│ └── utils
│ ├── config.py
│ ├── __init__.py
│ ├── logger.py # 日志相关模块代码库
│ └── session.py
├── docs
├── logs # 日志文件存储目录
│ └── mofang.log
└── manage.py
经过上面的改造,接下来就可以开始创建蓝图了。
七、蓝图初始化
在application下创建apps目录,apps以后专门用于保存每一个项目的蓝图,并在apps创建home蓝图目录,并在__init__.py
文件中创建蓝图对象
通过自定义终端命令, 创建一个自动生成蓝图目录的命令.application/utils/commands.py
,代码:
from flask_script import Command, Optionclass BlueprintCommand(Command):"""蓝图生成命令"""name = "blue"option_list = [Option('--name', '-n', dest='name'),]def run(self, name):# 生成蓝图名称对象的目录os.mkdir(name)open("%s/__init__.py" % name, "w")open("%s/views.py" % name, "w")open("%s/models.py" % name, "w")with open("%s/urls.py" % name, "w") as f:content = """from . import views
from application.utils import path
urlpatterns = []"""f.write(content)print("蓝图%s创建完成...." % name)
上面的命令就可以帮我们完成项目中生成蓝图的功能,就下来我们就可以直接把命令注册到manage对象中就可以使用了.
但是, 我们往后的开发中肯定还会继续的需要进行自定义终端命令,所以我们声明一个load_command的函数,让自动帮我们完成加载注册自定义终端命令的过程.
application/utils/commands.py
,代码:
import os
from importlib import import_module
from flask_script import Command, Option
import inspectdef load_command(manager,command_path=None):"""自动加载自定义终端命令"""if command_path is None:command_path = "application.utils.commands"module = import_module(command_path)class_list = inspect.getmembers(module,inspect.isclass)for class_item in class_list:if issubclass(class_item[1],Command) and class_item[0] != "Command":manager.add_command(class_item[1].name,class_item[1])class BlueprintCommand(Command):"""蓝图生成命令"""name = "blue"option_list = [Option('--name', '-n', dest='name'),]def run(self, name):# 生成蓝图名称对象的目录os.mkdir(name)open("%s/__init__.py" % name, "w")open("%s/views.py" % name, "w")open("%s/models.py" % name, "w")with open("%s/urls.py" % name, "w") as f:content = """from . import views
from application.utils import path
urlpatterns = []"""f.write(content)print("蓝图%s创建完成...." % name)
在项目全局引导文件application/__init__.py
中, 调用load_command函数注册命令
import os,loggingfrom flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_migrate import Migrate,MigrateCommandfrom application.utils.config import load_config
from application.utils.session import init_session
from application.utils.logger import Log
from application.utils.commands import load_command
# 创建终端脚本管理对象
manager = Manager()# 创建数据库链接对象
db = SQLAlchemy()# redis链接对象
redis = FlaskRedis()# Session存储对象
session_store = Session()# 数据迁移实例对象
migrate = Migrate()# 日志对象
log = Log()def init_app(config_path):"""全局初始化"""# 创建app应用对象app = Flask(__name__)app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 加载配置Config = load_config(config_path)app.config.from_object(Config)# 数据库初始化db.init_app(app)redis.init_app(app)# session存储初始化init_session(app)session_store.init_app(app)# 数据迁移初始化migrate.init_app(app,db)# 添加数据迁移的命令到终端脚本工具中manager.add_command('db', MigrateCommand)# 日志初始化app.log = log.init_app(app)# 初始化终端脚本工具manager.app = app# 注册自定义命令load_command(manager)return manager
接下来就可以在终端下,通过命令生成蓝图目录了.
命令:
cd application/apps
python ../../manage.py blue -nhome
有了蓝图以后,接下来我们就可以编写视图代码,模型代码,路由代码等存储到蓝图目录下了,但是我们需要把蓝图注册到app应用对象下.所以我们注册蓝图这块代码也可以封装到一个函数中.让程序自动识别并注册.
项目中可以有多个蓝图,但是有些蓝图可能并不能提供给客户端访问,所以我们需要在配置文件中声明一个蓝图注册列表, 在init_blueprint
函数中只注册配置列表的蓝图
application/settings/__init__.py
,代码:
class InitConfig():"""项目默认初始化配置"""# 调试模式DEBUG = True# 数据库相关配置SQLALCHEMY_DATABASE_URI = ""# 动态追踪修改设置SQLALCHEMY_TRACK_MODIFICATIONS = False# 查询时会显示原始SQL语句SQLALCHEMY_ECHO= True# RedisREDIS_URL = ""# 设置密钥,可以通过 base64.b64encode(os.urandom(48)) 来生成一个指定长度的随机字符串SECRET_KEY = "y58Rsqzmts6VCBRHes1Sf2DHdGJaGqPMi6GYpBS4CKyCdi42KLSs9TQVTauZMLMw"# session存储配置# session存储方式配置SESSION_TYPE = "redis"# 如果设置session的生命周期是否是会话期, 为True,则关闭浏览器session就失效SESSION_PERMANENT = False# 设置session_id在浏览器中的cookie有效期PERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # session 的有效期,单位是秒# 是否对发送到浏览器上session的cookie值进行加密SESSION_USE_SIGNER = True# 保存到redis的session数的名称前缀SESSION_KEY_PREFIX = "session:"# session保存数据到redis时启用的链接对象SESSION_REDIS = None # 用于连接redis的配置SESSION_REDIS_HOST = "127.0.0.1"SESSION_REDIS_PORT = 6379SESSION_REDIS_DB = 1# 调整json数据转换中文的配置JSON_AS_ASCII=False# 日志相关配置LOG_LEVEL = "INFO" # 日志输出到文件中的最低等级LOG_DIR = "logs/0.log" # 日志存储目录LOG_MAX_BYTES = 300 * 1024 * 1024 # 单个日志文件的存储上限[单位: b]LOG_BACKPU_COUNT = 20 # 日志文件的最大备份数量LOG_NAME = "flask" # 日志器的名字# 蓝图注册列表INSTALLED_APPS = []
application/settings/dev.py
,代码:
from . import InitConfig
class Config(InitConfig):"""项目开发环境下的配置"""DEBUG = True# 数据库SQLALCHEMY_DATABASE_URI = "mysql://mofang_user:mofang@127.0.0.1:3306/mofang?charset=utf8mb4"SQLALCHEMY_ECHO = True# redisREDIS_URL = "redis://@127.0.0.1:6379/0"# session存储配置SESSION_REDIS_HOST = "127.0.0.1"SESSION_REDIS_PORT = 6379SESSION_REDIS_DB = 1# 日志配置LOG_LEVEL = "DEBUG" # 日志输出到文件中的最低等级LOG_DIR = "/logs/mofang.log" # 日志存储目录LOG_MAX_BYTES = 300 * 1024 * 1024 # 单个日志文件的存储上限[单位: b]LOG_BACKPU_COUNT = 20 # 日志文件的最大备份数量LOG_NAME = "mofang" # 日志器名称# 注册蓝图INSTALLED_APPS = ["application.apps.home",]
在init_blueprint函数中,针对注册的蓝图列表注册到app应用对象里面,application/utils/__init__.py
,代码:
def init_blueprint(app):"""自动注册蓝图"""blueprint_path_list = app.config.get("INSTALLED_APPS")for blueprint_path in blueprint_path_list:blueprint_name = blueprint_path.split(".")[-1]# 自动创建蓝图对象blueprint = Blueprint(blueprint_name,blueprint_path)# 注册蓝图对象到app应用对象中app.register_blueprint(blueprint,url_prefix="")
项目全局引导文件中, 调用init_blueprint
方法, 自动注册蓝图.application/__init__.py
,代码:
import os,loggingfrom flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_migrate import Migrate,MigrateCommandfrom application.utils import init_blueprint
from application.utils.config import load_config
from application.utils.session import init_session
from application.utils.logger import Log
from application.utils.commands import load_command
# 创建终端脚本管理对象
manager = Manager()# 创建数据库链接对象
db = SQLAlchemy()# redis链接对象
redis = FlaskRedis()# Session存储对象
session_store = Session()# 数据迁移实例对象
migrate = Migrate()# 日志对象
log = Log()def init_app(config_path):"""全局初始化"""# 创建app应用对象app = Flask(__name__)app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# 加载配置Config = load_config(config_path)app.config.from_object(Config)# 数据库初始化db.init_app(app)redis.init_app(app)# session存储初始化init_session(app)session_store.init_app(app)# 数据迁移初始化migrate.init_app(app,db)# 添加数据迁移的命令到终端脚本工具中manager.add_command('db', MigrateCommand)# 日志初始化app.log = log.init_app(app)# 蓝图注册init_blueprint(app)# 初始化终端脚本工具manager.app = app# 注册自定义命令load_command(manager)return manager
注册了蓝图对象以后,蓝图下面的视图方法和视图对应的路由关系也要进行注册!
所以, 在蓝图home下面的urls.py文件中,通过path方法把url地址和视图方法进行处理成字典,然后把字典作为成员返回到变量urlpatterns列表中.
application/utils/__init__.py
,生成path函数,代码:
from flask import Blueprint
from importlib import import_module
def path(rule,func_view):# 把蓝图下视图和路由之间的映射关系处理成字典结构,方便后面注册蓝图的时候,直接传参return {"rule":rule,"view_func":func_view}
在蓝图下的urls.py中,注册视图和路由的关系,home.urls.py
,代码:
from . import views
from application.utils import path
urlpatterns = [path("/",views.index),
]
视图代码:
def index():return 'index'
在init_blueprint初始化蓝图的函数中, 生成蓝图对象以后自动加载并注册蓝图和视application/utils/__init__.py
,代码:
from flask import Blueprint
from importlib import import_module
def path(rule,func_view):# 把蓝图下视图和路由之间的映射关系处理成字典结构,方便后面注册蓝图的时候,直接传参return {"rule":rule,"view_func":func_view}def init_blueprint(app):"""自动注册蓝图"""blueprint_path_list = app.config.get("INSTALLED_APPS")for blueprint_path in blueprint_path_list:blueprint_name = blueprint_path.split(".")[-1]# 自动创建蓝图对象blueprint = Blueprint(blueprint_name,blueprint_path)# 蓝图自动注册和绑定视图和子路由url_module = import_module(blueprint_path+".urls") # 加载蓝图下的子路由文件for url in url_module.urlpatterns: # 遍历子路由中的所有路由关系blueprint.add_url_rule(**url) # 注册到蓝图下# 注册蓝图对象到app应用对象中app.register_blueprint(blueprint,url_prefix="")
此时, 运行项目,就允许蓝图中视图通过url地址提供给客户端访问了.
上面蓝图注册到app时, 没有设置url_prefix路由前缀, 接下来我们可以单独设置一个总路由application/urls.py
,进行路由前缀的设置.
在项目默认配置文件中,application/settings/__init__.py
,新增总路由的配置项
class InitConfig():"""项目默认初始化配置"""# 调试模式DEBUG = True# 数据库相关配置SQLALCHEMY_DATABASE_URI = ""# 动态追踪修改设置SQLALCHEMY_TRACK_MODIFICATIONS = False# 查询时会显示原始SQL语句SQLALCHEMY_ECHO= True# RedisREDIS_URL = ""# 设置密钥,可以通过 base64.b64encode(os.urandom(48)) 来生成一个指定长度的随机字符串SECRET_KEY = "y58Rsqzmts6VCBRHes1Sf2DHdGJaGqPMi6GYpBS4CKyCdi42KLSs9TQVTauZMLMw"# session存储配置# session存储方式配置SESSION_TYPE = "redis"# 如果设置session的生命周期是否是会话期, 为True,则关闭浏览器session就失效SESSION_PERMANENT = False# 设置session_id在浏览器中的cookie有效期PERMANENT_SESSION_LIFETIME = 24 * 60 * 60 # session 的有效期,单位是秒# 是否对发送到浏览器上session的cookie值进行加密SESSION_USE_SIGNER = True# 保存到redis的session数的名称前缀SESSION_KEY_PREFIX = "session:"# session保存数据到redis时启用的链接对象SESSION_REDIS = None # 用于连接redis的配置SESSION_REDIS_HOST = "127.0.0.1"SESSION_REDIS_PORT = 6379SESSION_REDIS_DB = 1# 调整json数据转换中文的配置JSON_AS_ASCII=False# 日志相关配置LOG_LEVEL = "INFO" # 日志输出到文件中的最低等级LOG_DIR = "logs/0.log" # 日志存储目录LOG_MAX_BYTES = 300 * 1024 * 1024 # 单个日志文件的存储上限[单位: b]LOG_BACKPU_COUNT = 20 # 日志文件的最大备份数量LOG_NAME = "flask" # 日志器的名字# 蓝图注册列表INSTALLED_APPS = []# 总路由URL_PATH = "application.urls"
创建总路由文件并注册蓝图和路由前缀的关系, application/urls.py
,代码:
from application.utils import include
urlpatterns = [include("","home.urls"),
]
接下来,在init_blueprint
蓝图初始化函数中新增判断识别路由前缀的代码; 同时, 把路由前缀和蓝图映射关系的处理代码封装成include
方法,方便以后需求变化时可以直接调整.
from flask import Blueprint
from importlib import import_module
def path(rule,func_view):# 把蓝图下视图和路由之间的映射关系处理成字典结构,方便后面注册蓝图的时候,直接传参return {"rule":rule,"view_func":func_view}def include(url_prefix, blueprint_path):"""把路由前缀和蓝图进行关系映射"""return {"url_prefix":url_prefix,"blueprint_path":blueprint_path}def init_blueprint(app):"""自动注册蓝图"""blueprint_path_list = app.config.get("INSTALLED_APPS")for blueprint_path in blueprint_path_list:blueprint_name = blueprint_path.split(".")[-1]# 自动创建蓝图对象blueprint = Blueprint(blueprint_name,blueprint_path)# 蓝图自动注册和绑定视图和子路由url_module = import_module(blueprint_path+".urls") # 加载蓝图下的子路由文件for url in url_module.urlpatterns: # 遍历子路由中的所有路由关系blueprint.add_url_rule(**url) # 注册到蓝图下# 读取总路由文件url_path = app.config.get("URL_PATH")urlpatterns = import_module(url_path).urlpatterns # 加载蓝图下的子路由文件url_prefix = "" # 蓝图路由前缀for urlpattern in urlpatterns:if urlpattern["blueprint_path"] == blueprint_name+".urls":url_prefix = urlpattern["url_prefix"]break# 注册蓝图对象到app应用对象中, url_prefix 蓝图的路由前缀app.register_blueprint(blueprint,url_prefix=url_prefix)
自动注册蓝图下的所有模型
在蓝图下的models.py中声明模型,例如:
from application import db
class User(db.Model):__tablename__ = "mf_user"id = db.Column(db.Integer, primary_key=True, comment="主键ID")name = db.Column(db.String(255), unique=True, comment="账户名")password = db.Column(db.String(255), comment="登录密码")ip_address = db.Column(db.String(255), index=True, comment="登录IP")def __repr__(self):return self.name
然后在终端下执行数据迁移
cd ../..
python manage.py db init
python manage.py db migrate -m "test"
上面的命令执行以后, 我们可以发现模型根本被flask进行识别到.所以我们需要把模型注册到flask项目中.
application/utils/__init__.py
,代码:
from flask import Blueprint
from importlib import import_module
def path(rule,func_view):# 把蓝图下视图和路由之间的映射关系处理成字典结构,方便后面注册蓝图的时候,直接传参return {"rule":rule,"view_func":func_view}def include(url_prefix, blueprint_path):"""把路由前缀和蓝图进行关系映射"""return {"url_prefix":url_prefix,"blueprint_path":blueprint_path}def init_blueprint(app):"""自动注册蓝图"""blueprint_path_list = app.config.get("INSTALLED_APPS")for blueprint_path in blueprint_path_list:blueprint_name = blueprint_path.split(".")[-1]# 自动创建蓝图对象blueprint = Blueprint(blueprint_name,blueprint_path)# 蓝图自动注册和绑定视图和子路由url_module = import_module(blueprint_path+".urls") # 加载蓝图下的子路由文件for url in url_module.urlpatterns: # 遍历子路由中的所有路由关系blueprint.add_url_rule(**url) # 注册到蓝图下# 读取总路由文件url_path = app.config.get("URL_PATH")urlpatterns = import_module(url_path).urlpatterns # 加载蓝图下的子路由文件url_prefix = "" # 蓝图路由前缀for urlpattern in urlpatterns:if urlpattern["blueprint_path"] == blueprint_name+".urls":url_prefix = urlpattern["url_prefix"]break# 注册模型import_module(blueprint_path+".models")# 注册蓝图对象到app应用对象中, url_prefix 蓝图的路由前缀app.register_blueprint(blueprint,url_prefix=url_prefix)
之后再执行:
python manage.py db migrate -m "test2"
python manage.py db upgrade
项目能自动加载总路由和蓝图路由以后的项目目录结构,如下:
项目根目录/
├── application/ # 项目主要逻辑代码保存目录
| ├── settings/ # 项目配置存储目录
│ │ ├ __init__.py # 项目默认初始化配置文件
│ │ ├ dev.py # 开发阶段的配置文件
│ │ └ prod.py # 生产阶段的配置文件
│ ├── __init__.py # 项目初始化全局引导文件
| ├── utils/ # 项目工具类库目录
│ │ ├ commands.py # 自定义命令和加载命令的相关函数
│ │ ├ config.py # 项目配置加载的辅助函数
│ │ ├ session.py # 项目存储session相关的函数
│ │ └ logger.py # 日志模块
│ ├── apps/ # 保存项目中所有蓝图的存储目录
│ │ ├── home # 蓝图目录【这里是举例而已】
│ │ │ ├── __init__.py # 蓝图的初始化文件
│ │ │ ├── urls.py # 蓝图的子路由文件
│ │ │ ├── models.py # 蓝图的模型文件
│ │ │ └── views.py # 蓝图的视图文件
│ │ ├── __init__.py
│ └── urls.py # 总路由
├── manage.py # 项目的终端管理脚本文件
魔方APP项目-02-服务端项目搭建,创建manage.py文件、构建全局初始化函数创建app应用对象、通过终端脚本启动项目、项目加载配置、数据库初始化、日志初始化、蓝图初始化相关推荐
- 微信app支付功能-服务端的实现-python3版
微信app支付功能-服务端的实现-python3版 一:需求说明 二:微信app支付处理流程 三:所需依赖 3.1 支付配置 四:接口开发 4.1 创建订单接口 4.2 微信异步回调接口 4.3 订单 ...
- 支付宝app支付功能-服务端的实现-python3版
支付宝app支付功能-服务端的实现-python3版 一:需求说明 二:支付宝app支付处理流程 三:所需依赖 3.1 依赖库 3.2 支付配置 3.2.1 沙箱环境配置 3.2.2 正式环境配置 四 ...
- android 快传 源码_安卓APP仿茄子快传源码,Android项目源码类似茄子快传的快传项目包括服务端...
适用范围:安卓APP仿茄子快传源码,Android项目源码类似茄子快传的快传项目包括服务端 演示地址:(以截图为准) 运行环境:Android+PC+web 其他说明: 本项目是一个基于安卓的类似茄子 ...
- 【DDD/CQRS/微服务架构案例】在Ubuntu 14.04.4 LTS中运行WeText项目的服务端
在<WeText项目:一个基于.NET实现的DDD.CQRS与微服务架构的演示案例>文章中,我介绍了自己用Visual Studio 2015(C# 6.0 with .NET Frame ...
- 小歆记账 php,小歆记账WebApp项目(Web服务端)
小歆记账WebApp项目(Web服务端) V2.x版本 | V1.x版本 | 基础版本 | 微信小程序 1.简介 小歆记账WebApp是一个面向移动端的记账工具,此项目为Web服务端:使用ThinkP ...
- php开源 饭馆记账软件_GitHub - CNYoki/xxjzWeb: 小歆记账WebApp项目(Web服务端)
小歆记账WebApp项目(Web服务端) 1.简介 小歆记账WebApp是一个面向移动端的记账工具,此项目为Web服务端:使用ThinkPHP+MySQL作为后台,AmazeUI作为前端. 项目基础版 ...
- app及Java服务端实现JT808协议的定义解析
app及Java服务端实现JT808协议的定义解析,可以用做行车记录仪等的app. 网上很多帖子已经对JT808协议做了说明,我在这里就不做过多的赘述了. 最近接到一个项目是打车类的,所以对这协议做了 ...
- 阿拉德手游服务端Centos搭建教程
阿拉德手游服务端Centos搭建教程 大家好我是艾西,又有几天没有更新文章了.这几天看了看还是有不少人对手游感兴趣,今天给大家分享一款早些年大火的pc游戏,现在也有手游了"阿拉德" ...
- SVN服务端的搭建和简单使用
SVN简单说明 SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Su ...
最新文章
- 这些SpringBoot天生自带Buff工具类你都用过哪些?
- 《Unity 4 3D开发实战详解》一6.7 物理引擎综合案例
- Spark源码阅读03-Spark存储原理之存储分析
- android studio编辑页面案例,2.4、Android Studio使用主题编辑器设计主题
- linux图机界面机制
- HDU4706 Children's Day
- 前后端分离项目如何部署_不用Docker前后端分离项目如何快速部署
- springmvc注解详解
- python解析visio_再见,Visio!
- 总有阳光照射不见的地方
- 【插值】插值方法原理详解
- Nature:为什么免疫系统可产生多样性抗体和T细胞受体?
- C++ string切割,分解字符串,C 库函数 - strtok()
- HTML如何返回上一页?
- 《深入理解Android内核设计思想(第2版)(上下册)》之Android源码下载及编译...
- 小实验----Cobbler自动化部署装机
- 利用Adobe Acrobat 7.0 Professional 自带的导出图片的功能(转)
- [译] 冲冠一怒为代码:论程序员与负能量
- matlab学习笔记(十五)---综合实例
- 基于matlab的谐振电路仿真,基于Matlab的LC并联谐振回路的建模与仿真