
株式会社フルネスから2023年9月に刊行された「Flask 本格入門-やさしくわかるWebアプリ開発」〔樹下雅章著〕は、説明がとても丁寧で分かり易く応用の利く好著ですが、サイト管理者(筆者)の場合、題材のメモアプリのメモが編集できませんでした。メモのタイトルが同じ場合は、新規登録も更新もできないように独自バリデーションが追記されているためです。この独自バリデーションの前後で新規登録か編集かのいずれかであることの場合分けが必要でした。
編集画面でコンテンツ(内容)だけ修正して登録しようとすると次のようになります。
これは、バリデーションを記したforms.pyで次のように独自バリデーションが追記されているためです。
この問題を回避するために、モジュール間で共通に使える変数を確保する必要がありますが、いろいろ調べてみましたら、Pkythonの言語説明サイトに記してありました(https://docs.python.org/ja/3/faq/programming.html#how-do-i-share-global-variables-across-modules)。
一つのプログラムのモジュール間で情報を共有する正準な方法は、特別なモジュール (しばしば config や cfg と呼ばれる) を作ることです。単に設定モジュールをアプリケーションのすべてのモジュールにインポートしてください。このモジュールはグローバルな名前として使えます。それぞれのモジュールのただ一つのインスタンスがあるので、設定モジュールオブジェクトに対するいかなる変更も全体に反映されます。例えば:
config.py:
x = 0 # Default value of the 'x' configuration settingmod.py:
import config config.x = 1main.py:
import config import mod print(config.x)なお、同じ理由から、モジュールを使うということは、シングルトンデザインパターンを実装することの基礎でもあります。
サイト管理者(筆者)の場合は、ルートのディレクトリにcommon.pyというファイルを作り、次のように書いたうえで、memo/views.pyとforms.pyを少し修正しました。
まず、commons.pyです。
次に、memo/views.pyです。
@memo_bp.route("/update/", methods=['GET', 'POST'])
@login_required
def update(memo_id):
# アップデートであることを示す
common.is_update = True
# データベースからmemo_idに一致するメモを取得し、見つからない場合は404エラーを表示
target_data = Memo.query.filter_by(id=memo_id, user_id=current_user.id).first_or_404()
form = MemoForm(obj=target_data)
if request.method == 'POST' and form.validate():
target_data.title = form.title.data
target_data.content = form.content.data
db.session.merge(target_data)
db.session.commit()
flash("変更しました。")
return redirect(url_for("memo.index"))
# GET
return render_template("memo/update_form.html", form=form, edit_id=target_data.id)
モジュール間の共通変数としてのis_updateをTrueとして、forms.pyに知らせるようにします。
# メモ用入力クラス
class MemoForm(FlaskForm):
title = StringField('タイトル', validators=[DataRequired('タイトルは必須入力です'),
Length(max=20, message='20文字以下で入力して下さい')])
content = TextAreaField('内容')
submit = SubmitField('送信')def validate_title(self, title):
memo = Memo.query.filter_by(title=title.data).first()
if memo:
if common.is_update == False:
raise ValidationError(f"タイトル'(title.data)は既に存在します。")
else:
common.is_update = True
これで、編集時(修正時)には独自バリデーションが効かなくなります。なお、各モジュールではcommon.pyモジュールのインポートが必要です。
ちょっとした修正ですが、その結果次の画像のように編集できるようになりました。

本件を除いて「Flask本格入門」にソース・コードに問題はありませんでした。好著でありましたが、Flaskがマイクロフレームワークとして優れていることをあますことなく紹介しています。
【追記】第17章のマイクロ・サービスのところで、hello-appディレクトリ配下のapp.py、login.htmlともに「shwo_login」となっていますが、「show_login」でも動作します。




















