伊達要一@とうきょうDD954の書棚と雑記

伊達要一の読んだ本の紹介と書評、それと雑記

【Python/Django】メッセージフレームワークの使い方

f:id:yohichidate:20170608155451p:plain
ちょっとピンポイント過ぎるネタですが、これを写経してて個人的にハマったのでメモ。

元ネタ? というか公式のドキュメントの該当ページはこちら。
メッセージフレームワーク | Django documentation | Django
基本的にこれに対してメモ的に色々書いていく感じで。

メッセージフレームワークとは?

Web アプリケーションでは非常に一般的に、フォームやその他のユーザーインプットのプロセスの後、ユーザーに向けて一過性の通知メッセージ ("フラッシュメッセージ" とも言われます) を表示する必要があります。


Django は、anonymous および認証済みユーザーの両方に対して、Cookie とセッションをベースにしたメッセージングを完全にサポートしています。このメッセージフレームワークは、一時的に一つのリクエスト内にメッセージを保管し、その後のリクエスト (通常、直後のリクエスト) 内で表示するために、これらを検索することを可能にします。全てのメッセージは、優先順位 (例えば infowarning、ないし error) を決定づける特定の level でタグづけされます。

メッセージフレームワーク | Django documentation | Django

メッセージフレームワークを簡単に云うと「システムに対してユーザがアクションをしたときに、その結果をメッセージとして返してやるための仕組み」ということ。
Django は、匿名(anonymous)でも認証済みのユーザでも、Cookie とセッションをもとに結果をメッセージとして返してやることが出来る。

メッセージを有効にする方法

メッセージは、 ミドルウェア クラスと、それに対応する コンテクストプロセッサー を通して実行されます。


django-admin startproject によって生成されたデフォルトの settings.py は、メッセージ機能を有効にするために必要な設定を全て含んでいます:

  • 'django.contrib.messages' は、INSTALLED_APPS の中にあります。
  • MIDDLEWARE'django.contrib.sessions.middleware.SessionMiddleware''django.contrib.messages.middleware.MessageMiddleware' を含みます。デフォルトの storage backend は sessions に依存します。そのため SessionMiddleware を有効にして、 MIDDLEWARE 内で MessageMiddleware より前に記述する必要があります。
  • TEMPLATES 設定で定義した DjangoTemplates バックエンドの 'context_processors' オプションは、'django.contrib.messages.context_processors.messages' を含みます。


メッセージを使いたくない場合は、INSTALLED_APPS から 'django.contrib.messages' を、MIDDLEWARE から MessageMiddleware 行を、そして TEMPLATES から messages コンテクストプロセッサーを削除できます。

メッセージフレームワーク | Django documentation | Django

長々書いているけど、

  • startapp で作ったときにはデフォルトで使えるようになっている
  • 小細工をしたいときには色々気をつけてね

という話。

ビューでメッセージを付与する

一番書きたいネタ。簡単にサンプルコードをドキュメントから引用。views.pyに書く。

from django.contrib import messages
# 中略
messages.add_message(request, messages.INFO, 'Hello, world.')

messages.add_message()の第2引数「messages.INFO」の「INFO」部分に関しては、以下のパターンがある。

定数 目的
DEBUG プロダクション環境では無視 (ないし削除) される、開発に関連したメッセージ
INFO ユーザーに何か情報を伝えるメッセージ
SUCCESS あるアクションが成功した、例えば "あなたのプロフィールは無事に更新されました"
WARNING 問題は起きなかったが、問題になり得る
ERROR あるアクションが成功 しなかった か、他の問題が発生した

定数の目的に合致したメッセージを上述した実装方法で定義してやれば良い。

別の実装方法はこちら。ってか、こっちの方がメインなのかも。

from django.contrib import messages
# 中略
messages.debug(request, '%s SQL statements were executed.' % count)
messages.info(request, 'Three credits remain in your account.')
messages.success(request, 'Profile details updated.')
messages.warning(request, 'Your account expires in three days.')
messages.error(request, 'Document deleted.')

使う際には「from django.contrib import messages」としてやらないと、処理内で「messages.success(request, 'OK')」とか書いたときに、「NameError: name 'messages' is not defined」とエラーが発生する。

他のナレッジについてはこちら。
yohichidate.hatenablog.com