| -flasky
| -app/
|-init.py
|-email.py
|-models.py
|-templates/
|-statics/
|-main/
|-init.py
|-errors.py
|-forms.py
|-views.py
|-migrations/
|-tests/
|-init.py
|-test*.py
|-venv/
|-requirements.txt
|-config.py
|-flasky.py

有四个顶级目录:
Flask应用保存在app包中;
数据库迁移脚本在migrations文件夹中;
单元测试在tests包中编写;
虚拟环境在venv文件夹中。

requirement.txt列出所有依赖包
config.py存储配置
flask.py定义Flask应用实例,同时还有一些辅助管理应用的任务。

config.py

config.py中设置一些参数,建议把邮箱敏感信息配置到系统参数内

  1. import os
  2. basedir = os.path.abspath(os.path.dirname(__file__))
  3. class Config:
  4. SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
  5. MAIL_SERVER = os.environ.get('MAIL_SERVER', 'smtp.googlemail.com')
  6. MAIL_PORT = int(os.environ.get('MAIL_PORT', '587'))
  7. MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS', 'true').lower() in \
  8. ['true', 'on', '1']
  9. MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
  10. MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
  11. FLASKY_MAIL_SUBJECT_PREFIX = '[Flasky]'
  12. FLASKY_MAIL_SENDER = 'Flasky Admin <flasky@example.com>'
  13. FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN')
  14. SQLALCHEMY_TRACK_MODIFICATIONS = False
  15. @staticmethod
  16. def init_app(app):
  17. pass
  18. class DevelopmentConfig(Config):
  19. DEBUG = True
  20. SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or \
  21. 'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
  22. class TestingConfig(Config):
  23. TESTING = True
  24. SQLALCHEMY_DATABASE_URI = os.environ.get('TEST_DATABASE_URL') or \
  25. 'sqlite://'
  26. class ProductionConfig(Config):
  27. SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
  28. 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
  29. config = {
  30. 'development': DevelopmentConfig,
  31. 'testing': TestingConfig,
  32. 'production': ProductionConfig,
  33. 'default': DevelopmentConfig
  34. }

应用

在app/init.py中,使用工厂函数

  1. from flask import Flask, render_template
  2. from flask_bootstrap import Bootstrap from flask_mail import Mail
  3. from flask_moment import Moment
  4. from flask_sqlalchemy import SQLAlchemy from config import config
  5. bootstrap = Bootstrap() mail = Mail()
  6. moment = Moment() db = SQLAlchemy()
  7. def create_app(config_name):
  8. app = Flask( name )
  9. app.config.from_object(config[config_name])
  10. config[config_name].init_app(app)
  11. bootstrap.init_app(app)
  12. mail.init_app(app)
  13. moment.init_app(app) db.init_app(app)
  14. # 添加路由和自定义的错误页面
  15. return app

在app/main/init.py中,书上是这么写的,在末尾引入views和errors说是为了避免循环导入依赖

  1. from flask import Blueprint
  2. main = Blueprint('main', __name__)
  3. from . import views, errors

errors.py

  1. from flask import render_template
  2. from . import main
  3. @main.app_errorhandler(404)
  4. def page_not_found(e):
  5. return render_template('404.html'), 404
  6. @main.app_errorhandler(500)
  7. def internal_server_error(e):
  8. return render_template('500.html'), 500

flasy.py

其中@app.shell_context_processor装饰器,会创建并注册一个shell上下文处理器
调用flask的shell时,可以设置环境变量FLASK_APP=flasky.py

  1. import os
  2. from app import create_app, db
  3. from app.models import User, Role
  4. from flask_migrate import Migrate
  5. app = create_app(os.getenv('FLASK_CONFIG') or 'default')
  6. migrate = Migrate(app, db)
  7. @app.shell_context_processor
  8. def make_shell_context():
  9. return dict(db=db, User=User, Role=Role)

依赖文件

创建当前依赖文件:
pip freeze>requirements.txt
安装requirements.txt中的依赖
pip install -r requirements.txt

七月老师的目录树结构是这样的:

app
app.py
config
secure.py
setting.py
project_name.py

在app.py中设置一个create_app,和一个register_blueprint,在create_app中调用register_blueprint把蓝图注册到app中,然后引用config文件下的配置文件,project_name.py从app生成一个app,然后启动。