メッセージフレームワーク
Webアプリケーションでは非常に一般的に、フォームまたはその他の種類のユーザー入力を処理した後、ユーザーに1回限りの通知メッセージ(「フラッシュメッセージ」とも呼ばれます)を表示する必要があります。
このため、Djangoは、匿名ユーザーと認証済みユーザーの両方に対して、Cookieベースおよびセッションベースのメッセージングを完全にサポートします。 メッセージフレームワークを使用すると、1つのリクエストにメッセージを一時的に保存し、後続のリクエスト(通常は次のリクエスト)で表示するためにメッセージを取得できます。 すべてのメッセージは、その優先度を決定する特定のlevel
でタグ付けされます(たとえば、info
、warning
、またはerror
)。
メッセージの有効化
メッセージは、ミドルウェアクラスおよび対応するコンテキストプロセッサを介して実装されます。
django-admin startproject
によって作成されたデフォルトのsettings.py
には、メッセージ機能を有効にするために必要なすべての設定がすでに含まれています。
'django.contrib.messages'
は:setting: `INSTALLED_APPS` にあります。:setting: `MIDDLEWARE` には、
'django.contrib.sessions.middleware.SessionMiddleware'
と'django.contrib.messages.middleware.MessageMiddleware'
が含まれています。デフォルトのストレージバックエンドはセッションに依存しています。 そのため、
SessionMiddleware
を有効にして、:setting: `MIDDLEWARE` のMessageMiddleware
の前に表示する必要があります。:setting: `TEMPLATES` 設定で定義された
DjangoTemplates
バックエンドの'context_processors'
オプションには、'django.contrib.messages.context_processors.messages'
が含まれています。
メッセージを使用したくない場合は、:setting: `INSTALLED_APPS` から'django.contrib.messages'
を削除し、:setting:`からMessageMiddleware
行を削除できます。 MIDDLEWARE` 、および:setting: `TEMPLATES` のmessages
コンテキストプロセッサ。
メッセージエンジンの構成
ストレージバックエンド
メッセージフレームワークは、さまざまなバックエンドを使用して一時的なメッセージを格納できます。
Djangoは、 django.contrib.messages で3つの組み込みストレージクラスを提供します。
- class storage.session.SessionStorage
- このクラスは、リクエストのセッション内にすべてのメッセージを格納します。 したがって、Djangoの
contrib.sessions
アプリケーションが必要です。
- class storage.cookie.CookieStorage
- このクラスは、メッセージデータをCookie(操作を防ぐために秘密のハッシュで署名されたもの)に格納して、要求間で通知を永続化します。 Cookieのデータサイズが2048バイトを超える場合、古いメッセージは削除されます。
- class storage.fallback.FallbackStorage
このクラスは最初に
CookieStorage
を使用し、単一のCookieに収まらないメッセージにはSessionStorage
を使用するようにフォールバックします。 また、Djangoのcontrib.sessions
アプリケーションも必要です。この動作により、可能な限りセッションへの書き込みが回避されます。 一般的な場合に最高のパフォーマンスを提供するはずです。
FallbackStorage はデフォルトのストレージクラスです。 ニーズに合わない場合は、:setting: `MESSAGE_STORAGE` を完全なインポートパスに設定して、別のストレージクラスを選択できます。次に例を示します。
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
- class storage.base.BaseStorage
独自のストレージクラスを作成するには、BaseStorage
クラスをdjango.contrib.messages.storage.base
にサブクラス化し、_get
メソッドと_store
メソッドを実装します。
メッセージレベル
メッセージフレームワークは、Pythonロギングモジュールと同様の構成可能なレベルのアーキテクチャに基づいています。 メッセージレベルを使用すると、メッセージをタイプ別にグループ化できるため、ビューやテンプレートでメッセージをフィルタリングしたり、異なる方法で表示したりできます。
django.contrib.messages
から直接インポートできる組み込みレベルは次のとおりです。
絶え間ない | 目的 |
---|---|
DEBUG
|
本番デプロイメントで無視(または削除)される開発関連メッセージ |
INFO
|
ユーザーへの情報メッセージ |
SUCCESS
|
アクションは成功しました、例えば 「プロファイルが正常に更新されました」 |
WARNING
|
障害は発生しませんでしたが、差し迫っている可能性があります |
ERROR
|
アクションが失敗成功したか、その他の障害が発生しました |
:setting: `MESSAGE_LEVEL` 設定を使用して、最小記録レベルを変更できます(または、リクエストごとにを変更できます)。 これより低いレベルのメッセージを追加しようとしても無視されます。
ビューとテンプレートでのメッセージの使用
- add_message(request, level, message, extra_tags=, fail_silently=False)
メッセージの追加
メッセージを追加するには、次の電話番号に電話してください。
from django.contrib import messages
messages.add_message(request, messages.INFO, 'Hello world.')
一部のショートカットメソッドは、一般的に使用されるタグ(通常はメッセージのHTMLクラスとして表されます)を使用してメッセージを追加する標準的な方法を提供します。
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.')
メッセージの表示
- get_messages(request)
テンプレートで、次のようなものを使用します。
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
コンテキストプロセッサを使用している場合、テンプレートはRequestContext
でレンダリングする必要があります。 それ以外の場合は、messages
がテンプレートコンテキストで使用可能であることを確認してください。
メッセージが1つしかないことがわかっている場合でも、messages
シーケンスを繰り返す必要があります。そうしないと、次のリクエストでメッセージストレージがクリアされないためです。
コンテキストプロセッサは、メッセージレベル名を数値にマッピングするDEFAULT_MESSAGE_LEVELS
変数も提供します。
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}Important: {% endif %}
{{ message }}
</li>
{% endfor %}
</ul>
{% endif %}
テンプレート以外では、 get_messages()を使用できます。
from django.contrib.messages import get_messages
storage = get_messages(request)
for message in storage:
do_something_with_the_message(message)
たとえば、すべてのメッセージをフェッチして、 TemplateResponseMixin ではなく JSONResponseMixin で返すことができます。
get_messages()は、構成されたストレージバックエンドのインスタンスを返します。
Messageクラス
- class storage.base.Message
- テンプレート内のメッセージのリストをループすると、
Message
クラスのインスタンスが取得されます。 それらにはいくつかの属性しかありません。
message
:メッセージの実際のテキスト。level
:メッセージのタイプを説明する整数(上記のメッセージレベルセクションを参照)。tags
:スペースで区切られたすべてのメッセージのタグ(extra_tags
およびlevel_tag
)を組み合わせた文字列。extra_tags
:このメッセージのカスタムタグをスペースで区切って含む文字列。 デフォルトでは空です。level_tag
:レベルの文字列表現。 デフォルトでは、関連付けられた定数の名前の小文字バージョンですが、必要に応じて:setting: `MESSAGE_TAGS` 設定を使用して変更できます。
カスタムメッセージレベルの作成
メッセージレベルは整数にすぎないため、独自のレベル定数を定義し、それらを使用して、よりカスタマイズされたユーザーフィードバックを作成できます。例:
CRITICAL = 50
def my_view(request):
messages.add_message(request, CRITICAL, 'A serious error occurred.')
カスタムメッセージレベルを作成するときは、既存のレベルが過負荷にならないように注意する必要があります。 組み込みレベルの値は次のとおりです。
レベル定数 | 価値 |
---|---|
DEBUG
|
10 |
INFO
|
20 |
SUCCESS
|
25 |
WARNING
|
30 |
ERROR
|
40 |
HTMLまたはCSSでカスタムレベルを識別する必要がある場合は、:setting: `MESSAGE_TAGS` 設定を介してマッピングを提供する必要があります。
リクエストごとの最小記録レベルの変更
最小記録レベルは、set_level
メソッドを介してリクエストごとに設定できます。
from django.contrib import messages
# Change the messages level to ensure the debug message is added.
messages.set_level(request, messages.DEBUG)
messages.debug(request, 'Test message...')
# In another request, record only messages with a level of WARNING and higher
messages.set_level(request, messages.WARNING)
messages.success(request, 'Your profile was updated.') # ignored
messages.warning(request, 'Your account is about to expire.') # recorded
# Set the messages level back to default.
messages.set_level(request, None)
同様に、現在の有効レベルはget_level
で取得できます。
from django.contrib import messages
current_level = messages.get_level(request)
最小記録レベルの機能の詳細については、上記のメッセージレベルを参照してください。
メッセージフレームワークが無効になっているときにサイレントに失敗する
再利用可能なアプリ(または他のコード)を作成していて、メッセージング機能を含めたいが、ユーザーが望まない場合にそれを有効にするようにユーザーに要求したくない場合は、追加のキーワード引数を渡すことができます[ X220X] からadd_message
ファミリーのメソッドのいずれかに。 例えば:
messages.add_message(
request, messages.SUCCESS, 'Profile details updated.',
fail_silently=True,
)
messages.info(request, 'Hello world.', fail_silently=True)
ノート
fail_silently=True
を設定すると、メッセージフレームワークが無効になり、add_message
ファミリーのメソッドの1つを使用しようとしたときに発生するMessageFailure
のみが非表示になります。 他の理由で発生する可能性のある障害を隠すことはありません。
クラスベースのビューにメッセージを追加する
- class views.SuccessMessageMixin
- FormView ベースのクラスに成功メッセージ属性を追加します
- get_success_message(cleaned_data)
cleaned_data
は、文字列のフォーマットに使用されるフォームからクリーンアップされたデータです
サンプルviews.py :
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.edit import CreateView
from myapp.models import Author
class AuthorCreate(SuccessMessageMixin, CreateView):
model = Author
success_url = '/success/'
success_message = "%(name)s was created successfully"
form
からクリーンアップされたデータは、%(field_name)s
構文を使用した文字列補間に使用できます。 ModelFormsの場合、保存されたobject
からフィールドにアクセスする必要がある場合は、 get_success_message()メソッドをオーバーライドします。
ModelForms のviews.pyの例:
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.edit import CreateView
from myapp.models import ComplicatedModel
class ComplicatedCreate(SuccessMessageMixin, CreateView):
model = ComplicatedModel
success_url = '/success/'
success_message = "%(calculated_field)s was created successfully"
def get_success_message(self, cleaned_data):
return self.success_message % dict(
cleaned_data,
calculated_field=self.object.calculated_field,
)
メッセージの有効期限
メッセージは、ストレージインスタンスが繰り返されるときにクリアされるようにマークされます(そして、応答が処理されるときにクリアされます)。
メッセージがクリアされないようにするには、次の手順を繰り返した後、メッセージストレージをFalse
に設定します。
storage = messages.get_messages(request)
for message in storage:
do_something_with(message)
storage.used = False
並列リクエストの動作
Cookie(したがってセッション)の動作方法により、同じクライアントがメッセージを並行して設定または取得する複数のリクエストを行う場合の Cookieまたはセッションを利用するバックエンドの動作は定義されていません。 たとえば、クライアントが1つのウィンドウ(またはタブ)でメッセージを作成するリクエストを開始し、次に別のウィンドウで統合メッセージをフェッチするリクエストを開始した場合、最初のウィンドウがリダイレクトされる前に、メッセージが最初のウィンドウではなく2番目のウィンドウに表示されることがありますそれが期待されるかもしれないウィンドウ。
つまり、同じクライアントからの複数の同時リクエストが関係している場合、メッセージがメッセージを作成したのと同じウィンドウに配信される保証はなく、場合によってはまったく配信されないこともあります。 これは通常、ほとんどのアプリケーションでは問題ではなく、各ウィンドウ/タブに独自のブラウジングコンテキストがあるHTML5では問題にならないことに注意してください。
設定
いくつかの設定を使用すると、メッセージの動作を制御できます。
Cookieを使用するバックエンドの場合、Cookieの設定はセッションCookie設定から取得されます。
- :setting: `SESSION_COOKIE_DOMAIN`
- :setting: `SESSION_COOKIE_SECURE`
- :setting: `SESSION_COOKIE_HTTPONLY`