# Django 4.1.8.dev20230308103347 ドキュメント

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

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

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

## メッセージを有効にする

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

`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 は、`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` はデフォルトのストレージクラスです。もしあなたのニーズに合わないときは、 `MESSAGE_STORAGE` を完全な import パスに設定することで他のストレージクラスを選べます。例えば:

    MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'

class `storage.base.``BaseStorage`

独自のストレージクラスに書き込むためには、 `django.contrib.messages.storage.base` 内の `BaseStorage` クラスをサブクラス化して、 `_get` と `_store` メソッドを実装してください。

### メッセージレベル

メッセージフレームワークは、Python ロギングモジュールに似た、設定可能なレベルアーキテクチャに基づきます。メッセージレベルは、タイプによるグループメッセージを可能にします。これにより、ビューやテンプレートの中で異なるフィルターおよび表示ができるようになります。

`django.contrib.messages` から直接インポートできるビルトインのレベルは以下の通りです:

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

`MESSAGE_LEVEL` 設定は、最小限の記録されたレベルを変更するため (もしくは リクエストごとに変更 するため)に使うことができます。これ以下のレベルのメッセージを追加しようとしても無視されます。

### メッセージタグ

メッセージタグは、メッセージレベルの表現文字列に加えて、ビューの中で直接付与される追加のタグです (詳しくは、以下の 追加のメッセージタグを付与する をご覧ください )。タグは文字列で保管され、スペースによって区切られます。典型的には、メッセージタグは、メッセージタイプに基いてメッセージのスタイルをカスタマイズするために、CSS のクラスとして利用されます。デフォルトでは、それぞれのレベルは、レベル定数を小文字にした、単一のタグを持っています。

レベル定数 | タグ
--- | ---
`DEBUG` | `debug`
`INFO` | `info`
`SUCCESS` | `success`
`WARNING` | `warning`
`ERROR` | `error`

メッセージレベル (ビルトインないしカスタムのいずれか) のデフォルトのタグを変更するためには、 `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` をテンプレートコンテクストに対して有効にしてください。

Even if you know there is only one message, you should still iterate over the `messages` sequence, because otherwise the message storage will not be cleared for the next request.

コンテクストプロセッサーは、メッセージレベルの名前と数値を対応させた `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 の中にreturnすることができます。

`get_messages()` は設定されたストレージバックエンドのインスタンスを返します。

### `Message` クラス

class `storage.base.``Message`

  When you loop over the list of messages in a template, what you get are instances of the `Message` class. They have only a few attributes:

  - `message`: メッセージの実際のテキストです。
  - `level`: メッセージのタイプを説明する数値です (詳細は上述の message levels セクション)。
  - `tags`: スペースによって区切られた、全てのメッセージのタグを結合する文字列 (`extra_tags` と `level_tag`) です。
  - `extra_tags`: スペースによって区切られた、メッセージのカスタムタグを含む文字列です。空がデフォルトです。
  - `level_tag`: レベルを表す文字列です。デフォルトでは定数名の小文字バージョンですが、`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 の中で独自のレベルを指定する必要がある場合は、`MESSAGE_TAGS` 設定を通してマップを提供する必要があります。

注釈

再利用可能なアプリケーションを作成している場合には、ビルトインの message levels だけを使い、独自のレベルに依存しないことが推奨されます。

### Changing the minimum recorded level per-request

The minimum recorded level can be set per request via the `set_level` method:

    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)

Similarly, the current effective level can be retrieved with `get_level`:

    from django.contrib import messages
    current_level = messages.get_level(request)

For more information on how the minimum recorded level functions, see Message levels above.

### Adding extra message tags

For more direct control over message tags, you can optionally provide a string containing extra tags to any of the add methods:

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

Extra tags are added before the default tag for that level and are space separated.

### Failing silently when the message framework is disabled

If you're writing a reusable app (or other piece of code) and want to include messaging functionality, but don't want to require your users to enable it if they don't want to, you may pass an additional keyword argument `fail_silently=True` to any of the `add_message` family of methods. For example:

    messages.add_message(
        request, messages.SUCCESS, 'Profile details updated.',
        fail_silently=True,
    )
    messages.info(request, 'Hello world.', fail_silently=True)

注釈

Setting `fail_silently=True` only hides the `MessageFailure` that would otherwise occur when the messages framework disabled and one attempts to use one of the `add_message` family of methods. It does not hide failures that may occur for other reasons.

### Adding messages in class-based views

class `views.``SuccessMessageMixin`

  Adds a success message attribute to `FormView` based classes

  `get_success_message`(cleaned_data)

    `cleaned_data` is the cleaned data from the form which is used for string formatting

Example 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"

The cleaned data from the `form` is available for string interpolation using the `%(field_name)s` syntax. For ModelForms, if you need access to fields from the saved `object` override the `get_success_message()` method.

Example views.py for ModelForms:

    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,
            )

## Expiration of messages

The messages are marked to be cleared when the storage instance is iterated (and cleared when the response is processed).

To avoid the messages being cleared, you can set the messages storage to `False` after iterating:

    storage = messages.get_messages(request)
    for message in storage:
        do_something_with(message)
    storage.used = False

## Behavior of parallel requests

Due to the way cookies (and hence sessions) work, the behavior of any backends that make use of cookies or sessions is undefined when the same client makes multiple requests that set or get messages in parallel. For example, if a client initiates a request that creates a message in one window (or tab) and then another that fetches any uniterated messages in another window, before the first window redirects, the message may appear in the second window instead of the first window where it may be expected.

In short, when multiple simultaneous requests from the same client are involved, messages are not guaranteed to be delivered to the same window that created them nor, in some cases, at all. Note that this is typically not a problem in most applications and will become a non-issue in HTML5, where each window/tab will have its own browsing context.

## 設定

A few settings give you control over message behavior:

- `MESSAGE_LEVEL`
- `MESSAGE_STORAGE`
- `MESSAGE_TAGS`

For backends that use cookies, the settings for the cookie are taken from the session cookie settings:

- `SESSION_COOKIE_DOMAIN`
- `SESSION_COOKIE_SECURE`
- `SESSION_COOKIE_HTTPONLY`