1.準備工做python
2.建立項目啓動文件manage.pymysql
3.構建全局初始化函數並在函數內建立app應用對象redis
4.經過終端腳本啓動項目sql
5.項目加載配置數據庫
6.數據庫初始化json
1.SQLAlchemy初始化flask
2.Redis初始化api
1.經過終端命令建立藍圖,並在藍圖中生成view/model/url等文件
1.新建項目目錄mofangapi,並建立虛擬環境
mkvirtualenv mofang
2.安裝開發中使用的依賴模塊
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啓動項目的文件
from flask import Flask app = 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 # 項目的終端管理腳本文件
from flask import Flask def init_app(): """全局初始化""" app = Flask(__name__) # 建立APP應用對象 return app
2.在manage.py,中調用初始化函數,建立app應用對象,代碼:
from application import init_app app = init_app() # 建立app應用對象 @app.route('/') def index(): return 'index' if __name__ == '__main__': app.run()
from flask import Flask from flask_script import Manager manager = Manager() # 引入終端腳本管理對象 *** def init_app(): """全局初始化""" # 建立app應用對象 app = Flask(__name__) # 初始化終端腳本工具 *** manager.app = app return manager
將manage.py的app改成manage,代碼:
from application import init_app manage = init_app() @manage.app.route('/') def index(): return 'index' if __name__ == '__main__': manage.run()
運行項目的方式就要修改以下:
此時咱們就能夠經過以下指令去運行項目了
python manage.py runserver -h0.0.0.0 -p5000
1.在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.InitConfig else: return module.Config
class InitConfig(): """項目默認初始化配置""" DEBUG = True
固然, 項目開發過程完成之後確定會項目上線,因此針對配置文件,咱們能夠準備不一樣環境下的配置
application/settings/dev.py
,代碼:
from . import InitConfig class Config(InitConfig): """項目開發環境下的配置""" DEBUG = True
from . import InitConfig class Config(InitConfig): """項目運營環境下的配置""" DEBUG = False
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) # 調用utils裏本身已經寫好的load_config方法 app.config.from_object(Config) # 將配置類註冊到APP上 # 初始化終端腳本工具 manager.app = app return manager
4.在建立app對象的項目啓動文件manage.py中,設置配置
from application import init_app manage = init_app("application.settings.dev") # 設置默認項目使用的配置文件是dev.py @manage.app.route('/') def index(): return 'index' if __name__ == '__main__': manage.run()
class InitConfig(): """項目默認初始化配置""" # 調試模式 DEBUG = True # 數據庫相關配置 SQLALCHEMY_DATABASE_URI = "" # 動態追蹤修改設置 SQLALCHEMY_TRACK_MODIFICATIONS = False # 查詢時會顯示原始SQL語句 SQLALCHEMY_ECHO= True
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
3.在mysql終端下, 建立數據庫用戶,命令以下:
create database mofang charset=utf8mb4; # 針對當前數據庫配置帳戶信息 create user mofang_user identified by 'mofang'; grant all privileges on mofang.* to 'mofang_user'@'%'; flush privileges;
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 = app return manager
class InitConfig(): """項目默認初始化配置""" # 調試模式 DEBUG = True # 數據庫相關配置 SQLALCHEMY_DATABASE_URI = "" # 動態追蹤修改設置 SQLALCHEMY_TRACK_MODIFICATIONS = False # 查詢時會顯示原始SQL語句 SQLALCHEMY_ECHO= True # Redis REDIS_URL = "redis://@127.0.0.1:6379/0"
from flask import Flask from flask_script import Manager from flask_sqlalchemy import SQLAlchemy from flask_redis import FlaskRedis from 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) # redis數據庫初始化 *** # 初始化終端腳本工具 manager.app = app return manager
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)
class InitConfig(): """項目默認初始化配置""" # 調試模式 DEBUG = True # 數據庫相關配置 SQLALCHEMY_DATABASE_URI = "" # 動態追蹤修改設置 SQLALCHEMY_TRACK_MODIFICATIONS = False # 查詢時會顯示原始SQL語句 SQLALCHEMY_ECHO= True # Redis REDIS_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 = 6379 SESSION_REDIS_DB = 0
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 # redis *** REDIS_URL = "redis://@127.0.0.1:6379/0" # 0號redis庫用來存redis緩存 # session存儲配置 *** SESSION_REDIS_HOST = "127.0.0.1" SESSION_REDIS_PORT = 6379 SESSION_REDIS_DB = 1 # 1號redis庫用來存session
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 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配置 session_store.init_app(app) # session存儲初始化 # 初始化終端腳本工具 manager.app = app return manager
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,MigrateCommand # *** from 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 = app return 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日誌分析系統.
FATAL/CRITICAL = 致命的,危險的 ERROR = 錯誤 WARNING = 警告 INFO = 信息 DEBUG = 調試
import logging from logging.handlers import RotatingFileHandler class Log(): """日誌模塊""" def __init__(self, app=None): if app is not None: self.init_app(app) def init_app(self,app): self.app = app return 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_BACKPU_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
2.application/settings/__init__.py
代碼:
class InitConfig(): """項目默認初始化配置""" # 調試模式 DEBUG = True # 數據庫相關配置 SQLALCHEMY_DATABASE_URI = "" # 動態追蹤修改設置 SQLALCHEMY_TRACK_MODIFICATIONS = False # 查詢時會顯示原始SQL語句 SQLALCHEMY_ECHO= True # Redis REDIS_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 = 6379 SESSION_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" # 日誌器的名字
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 # redis REDIS_URL = "redis://@127.0.0.1:6379/0" # session存儲配置 SESSION_REDIS_HOST = "127.0.0.1" SESSION_REDIS_PORT = 6379 SESSION_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" # 日誌器名稱
import os,logging 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,MigrateCommand from 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 = app return 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
通過上面的改造,咱們接下來就能夠開始建立藍圖了。
from flask_script import Command, Option 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)
可是, 咱們日後的開發中確定還會繼續的須要進行自定義終端命令,因此咱們聲明一個load_command的函數,讓自動幫咱們完成加載註冊自定義終端命令的過程.
import os from importlib import import_module from flask_script import Command, Option import inspect def 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)
import os,logging 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,MigrateCommand 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) # 初始化終端腳本工具 manager.app = app # 註冊自定義命令 *** load_command(manager) return manager
命令:
cd application/apps
python ../../manage.py blue -nhome
效果:
項目中能夠有多個藍圖,可是有些藍圖可能並不能提供給客戶端訪問,因此咱們須要在配置文件中聲明一個藍圖註冊列表, 在init_blueprint
函數中只註冊配置列表的藍圖
class InitConfig(): """項目默認初始化配置""" # 調試模式 DEBUG = True # 數據庫相關配置 SQLALCHEMY_DATABASE_URI = "" # 動態追蹤修改設置 SQLALCHEMY_TRACK_MODIFICATIONS = False # 查詢時會顯示原始SQL語句 SQLALCHEMY_ECHO= True # Redis REDIS_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 = 6379 SESSION_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 = [ ]
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 # redis REDIS_URL = "redis://@127.0.0.1:6379/0" # session存儲配置 SESSION_REDIS_HOST = "127.0.0.1" SESSION_REDIS_PORT = 6379 SESSION_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", ]
2.在init_blueprint函數中,針對註冊的藍圖列表註冊到app應用對象裏面,
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="")
import os,logging 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,MigrateCommand from 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列表中.
from flask import Blueprint from importlib import import_module def path(rule,func_view): # 把藍圖下視圖和路由之間的映射關係處理成字典結構,方便後面註冊藍圖的時候,直接傳參 return {"rule":rule,"view_func":func_view}
from . import views from application.utils import path urlpatterns = [ path("/",views.index), ]
視圖代碼:
def index(): return 'index'
3.在init_blueprint初始化藍圖的函數中, 生成藍圖對象之後自動加載並註冊藍圖和視圖
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="")
上面藍圖註冊到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 # Redis REDIS_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 = 6379 SESSION_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"
from application.utils import include urlpatterns = [ include("","home.urls"), ]
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)
1.在藍圖下的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
2.而後在終端下執行數據遷移
cd ../.. python manage.py db init python manage.py db migrate -m "text"
3.上面的命令執行之後, 咱們能夠發現模型根本被flask進行識別到.因此咱們須要把模型註冊到flask項目中.
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)
項目能自動加載總路由和藍圖路由之後的項目目錄結構,以下:
項目根目錄/ ├── 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 # 項目的終端管理腳本文件