基本はpythonスクリプトがあるディレクトリを表すもので、中身は空でいいようだ。
つまり、メインのスクリプトがmanage.pyだとして
-+-manage.py | +-app-+-__init__.py | +-models.py
というような構成になっているとappフォルダにはスクリプトが入っているよという目印になる。こうなっているとmanage.pyにmodels.pyをモジュールとしてインポートするには
import app.models.py
もしくは
from app import models.py
とすると良くなる。
models.pyで定義したdbをインポートするなら
from app.models import db
なのだね。
さらにこの__init__.pyの中に
from flask import Flask app = Flask(__name__) app.config['DEBUG'] = True app.config['SECRET_KEY'] = 'hard to guess string' app.config['SQLALCHEMY_DATABASE_URI'] =\ 'mysql+pymysql://root:password@localhost/flaskdata' app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
と定義しておくとmanage.pyは
from app import app
を追加しておくだけで、上のapp = Flask(__name__)からapp.configまでを取り除ける。
なおその際、templatesフォルダもappフォルダの中に移動となる。
さらにさらに
この__init__.pyを
from flask import Flask app = Flask(__name__) app.config.from_object('app.config')
とだけにしてやって、新たにconfig.pyを同じ階層に作り
DEBUG = True SECRET_KEY = 'hard to guess string' SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:password@localhost/flaskdata' SQLALCHEMY_COMMIT_ON_TEARDOWN = True SQLALCHEMY_TRACK_MODIFICATIONS = False
としておくとこのconfigファイルから読み込んで同じ動作が可能。
なおapp.config.from_objectで読み取る場合変数名は大文字にしておく必要がある。
だいぶわかってきたぞ。
__init__.py
from flask import Flask app = Flask(__name__) app.config.from_object('app.config') from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy(app) from flask_bootstrap import Bootstrap bootstrap = Bootstrap(app) from flask_moment import Moment moment = Moment(app) from flask_script import Manager manager = Manager(app)
とdbとbootstrapとMomentもこちらに移して、manage.pyから該当する部分を削除
models.pyからも
from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy()
を削除し、かわりに
from app import db
を入れておく。
最終的にはmanage.pyには
from app import app, db from flask_script import Manager, Shell from flask_migrate import Migrate, MigrateCommand from app.models import User, Role migrate = Migrate(app, db) def make_shell_context(): return dict(app=app, db=db, User=User, Role=Role) manager.add_command("shell", Shell(make_context=make_shell_context)) manager.add_command("db", MigrateCommand) if __name__ == '__main__': manager.run()
だけが残り、view.pyに、描画関係の残り全部が移動する。
from flask import render_template, session, redirect, url_for from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import Required from app.models import User, Role from app import app, db, moment, manager class NameForm(FlaskForm): name = StringField('What is your name?', validators=[Required()]) submit = SubmitField('Submit') @app.errorhandler(404) def page_not_found(e): return render_template('404.html'), 404 @app.errorhandler(500) def internal_server_error(e): return render_template('500.html'), 500 @app.route('/', methods=['GET', 'POST']) def index(): form = NameForm() if form.validate_on_submit(): user = User.query.filter_by(username=form.name.data).first() if user is None: user = User(username=form.name.data) db.session.add(user) session['known'] = False else: session['known'] = True session['name'] = form.name.data return redirect(url_for('index')) return render_template('index.html', form=form, name=session.get('name'), known=session.get('known', False))
これで一応のファイル分割はできたことになるが、どうやらBlueprintなる機能があるらしく、それを使うととても便利らしい。
あとformも別ファイルにしてやったほうがスッキリするかもしれない。
現在のファイル構成
-+-manage.py | +-app-+-__init__.py | +-config.py | +-models.py | +-view.py | +-template-+-base.html | +-index.html
ここまで結構時間がかかったが、ここからデータベース本体の取扱を中心に進めていくことになるだろう(多分)