メッセージフレームワーク—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/ref/contrib/messages
移動先:案内検索

メッセージフレームワーク

Webアプリケーションでは非常に一般的に、フォームまたはその他の種類のユーザー入力を処理した後、ユーザーに1回限りの通知メッセージ(「フラッシュメッセージ」とも呼ばれます)を表示する必要があります。

このため、Djangoは、匿名ユーザーと認証済みユーザーの両方に対して、Cookieベースおよびセッションベースのメッセージングを完全にサポートします。 メッセージフレームワークを使用すると、1つのリクエストにメッセージを一時的に保存し、後続のリクエスト(通常は次のリクエスト)で表示するためにメッセージを取得できます。 すべてのメッセージは、その優先度を決定する特定のlevelでタグ付けされます(たとえば、infowarning、またはerror)。

メッセージの有効化

メッセージは、ミドルウェアクラスおよび対応するコンテキストプロセッサを介して実装されます。

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

メッセージを使用したくない場合は、: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バイトを超える場合、古いメッセージは削除されます。

バージョン3.2での変更:メッセージ形式が RFC 6265 準拠の形式に変更されました。

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` 設定を使用して、最小記録レベルを変更できます(または、リクエストごとにを変更できます)。 これより低いレベルのメッセージを追加しようとしても無視されます。


メッセージタグ

メッセージタグは、メッセージレベルと、ビューに直接追加された追加のタグの文字列表現です(詳細については、以下の追加のメッセージタグの追加を参照してください)。 タグは文字列に格納され、スペースで区切られます。 通常、メッセージタグはCSSクラスとして使用され、メッセージタイプに基づいてメッセージスタイルをカスタマイズします。 デフォルトでは、各レベルには、独自の定数の小文字バージョンである単一のタグがあります。

レベル定数 鬼ごっこ
DEBUG debug
INFO info
SUCCESS success
WARNING warning
ERROR error

メッセージレベル(組み込みまたはカスタム)のデフォルトタグを変更するには、:setting: `MESSAGE_TAGS` 設定を変更するレベルを含む辞書に設定します。 これによりデフォルトのタグが拡張されるため、オーバーライドするレベルのタグを指定するだけで済みます。

from django.contrib.messages import constants as messages
MESSAGE_TAGS = {
    messages.INFO: '',
    50: 'critical',
}

ビューとテンプレートでのメッセージの使用

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)

最小記録レベルの機能の詳細については、上記のメッセージレベルを参照してください。


メッセージタグを追加する

メッセージタグをより直接的に制御するために、オプションで、追加のタグを含む文字列を任意のaddメソッドに提供できます。

messages.add_message(request, messages.INFO, 'Over 9000!', extra_tags='dragonball')
messages.error(request, 'Email box full', extra_tags='email')

追加のタグは、そのレベルのデフォルトタグの前に追加され、スペースで区切られます。


メッセージフレームワークが無効になっているときにサイレントに失敗する

再利用可能なアプリ(または他のコード)を作成していて、メッセージング機能を含めたいが、ユーザーが望まない場合にそれを有効にするようにユーザーに要求したくない場合は、追加のキーワード引数を渡すことができます[ 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 AuthorCreateView(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 ComplicatedCreateView(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設定から取得されます。