# Dokumentasi Django 5.2.8

# Kerangka pesan

Cukup umum dalam aplikasi jaringan, anda butuh memasang pesan pemberitahuan satu-waktu (juga dikenal sebagai "flash message") pada pengguna setelah pengolahan sebuah formulir aau beberapa jenis lain dari masukan pengguna.

Untuk ini, Django menyediakan dukungan penuh untuk oesan berdasarkan-kue dan sesi, untuk kedua pengguna anonim dan terautentifikasi. Kerangka kerja pesan mengizinkan anda secara sementara menyimpan pesan dalam satu permintaan dam mengambil mereka untuk ditampilkan dalam permintaan selanjutnya (biasanya satu selanjutnya). Setiap pesan dietiket dengan `level` khusus yang menentukan keutamaannya (misalnya, `info`, `warning`, atau `error`).

## Mengadakan pesan

Pesan diterapkan melalui middleware class dan bersamaan context processor.

Awalan `settings.py` dibuat oleh `django-admin startproject` sudah mengandung semua pengaturan dibutuhkan untuk mengadakan pesan fungsionalitas:

- `'django.contrib.messages'` di `INSTALLED_APPS`.

- `MIDDLEWARE` mengandung `'django.contrib.sessions.middleware.SessionMiddleware'` dan `'django.contrib.messages.middleware.MessageMiddleware'`.

  storage backend awalan bergantung pada sessions. Itu mengapa `SessionMiddleware` harus diadakan dan muncul sebelum `MessageMiddleware` dalam `MIDDLEWARE`.

- Pilihan `'context_processors'` dari backend `DjangoTemplates` ditentukan di pengaturan `TEMPLATES` anda mengandung `'django.contrib.messages.context_processors.messages'`.

Jika anda tidak ingin menggunakan pesan-pesan, anda dapat memindahkan `'django.contrib.messages'` dari `INSTALLED_APPS` anda, baris `MessageMiddleware` dari `MIDDLEWARE`, dan pengolah konteks `messages` dari `TEMPLATES`.

## Konfigurasi mesin pesan

### Backend Penyimpanan

Kerangka kerja pesan-pesan dapat menggunakan backend berbeda untuk menyimpan pesan-pesan sementara.

Django menyediakan kelas-kelas penyimpanan siap-pakai di `django.contrib.messages`:

class storage.session.SessionStorage

  Kelas ini menyimpan semua pesan didalam sesi permintaan. Karena itu membutuhkan aplikasi `contrib.sessions` Django.

class storage.cookie.CookieStorage

  Kelas ini menyimpan data pesan dalam sebuah kue (ditandai dengan campuran rahasia untuk mencegah perubahan) untuk bertahan pemberitahuan terhadap permintaan. Pesan-pesan lama dibuang jika ukuran data kue akan melebihi 2048 byte.

class storage.fallback.FallbackStorage

  Kelas ini pertama menggunakan `CookieStorage`, dan jatuh kembali menggunakan `SessionStorage` untuk pesan yang tidak cocok dalam kue tunggal. Itu juga membutuhkan aplikasi `contrib.sessions` Django.

  Perilaku ini menghindari menulis ke sesi bilamana memungkinkan. Itu harus menyediakan penampilan terbaik di kasus umum.

`FallbackStorage` adalah kelas penyimpanan awalan. Jika itu tidak cocok pada kebutuhan anda, anda dapat memilih kelas penyimpanan lain dengan mengatur `MESSAGE_STORAGE` ke jalur impor penuhnya, sebagai contoh:

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

class storage.base.BaseStorage

Untuk menulis kelas penyimpanan sendiri, subkelas kelas `BaseStorage` di `django.contrib.messages.storage.base` dan menerapkan metode `_get` dan `_store`.

### Tingkatan pesan

Kerangka kerja pesan berdasarkan pada tingkat arsitektur dapat dikonfigurasikan mirip pada modul pencatatan Python. Tingkatan pesan mengizinkan anda mengelompokkan pesan berdasarkan jenis sehingga mereka dapat disaring atau ditampilkan berbeda dalam tampilan atau cetakan.

Tingkat siap-pakai, yang dapat diimpor dari `django.contrib.messages` secar langsung, adalah:

Ketetapan | Maksud
--- | ---
`DEBUG` | Pesan-pesan terkait-pengembangan yang akan diabaikan (atau dipindahkan) dalam penyebaran produksi
`INFO` | Pesan informasi untuk pengguna
`BERHASIL` | Sebuah tindakan telah berhasil, misalnya "Profil anda telah berhasil diperbaharui".
`PERINGATAN` | Kegagalan tidak muncul tetapi mungkin sebentar lagi
`KESALAHAN` | Sebuah tindakan tidak berhasil atau beberapa kegagalan lain muncul

Pengaturan `MESSAGE_LEVEL` dapat digunakan merubah tingkat perekaman minimal (atau itu dapat berupa changed per request). Usaha-usaha untuk menambahkan pesan-pesan dari tingkatan kurang dari ini akan diabaikan.

### Etiket pesan

Etiket-etiket pesan adalah sebuah perwakilan string dari tingkat pesan ditambah etiket-etiket tambahan apapun yang telah ditambahkan langsung dalam tampilan (lihat Adding extra message tags dibawah untuk rincian lebih). Etiket disimpan dalam sebuah string dan dipisahkan oleh ruang. Khususnya, etiket-etiket pesan digunakan sebagai kelas-kelas CSS untuk menyesuaikan gaya pesan berdasarkan pada jenis pesan. Secara awalan, setiap tingkat mempunyai etiket tunggal yaitu versi huruf kecil dari ketetapan miliknya.

Tingkat Ketetapan | Etiket
--- | ---
`DEBUG` | `debug`
`INFO` | `info`
`BERHASIL` | `berhasil`
`PERINGATAN` | `peringatan`
`KESALAHAN` | `kesalahan`

Untuk merubah etiket-etiket awalan untuk sebuah tingkat pesan (antara siap-pakai atau penyesuaian), setel pengaturan `MESSAGE_TAGS` pada sebuah dictionary mengandung tingkatan anda harap rubah. Ketika ini memperpanjang etiket-etiket awalan, anda hanya butuh menyediakan etiket-etiket untuk tingkatan-tingkatan anda harap timpa:

    from django.contrib.messages import constants as messages

    MESSAGE_TAGS = {
        messages.INFO: "",
        50: "critical",
    }

## Menggunakan pesan di tampilan dan cetakan

add_message(request, level, message, extra_tags='', fail_silently=False)

### Menambahkan pesan

Untuk menambahkan pesan, panggil:

    from django.contrib import messages

    messages.add_message(request, messages.INFO, "Hello world.")

Beberapa metode jalan pintas menyediakan cara standar untuk menambah pesan-pesan dengan umumnya menggunakan etiket-etiket (yang biasanya diwakili sebagai kelas-kelas HTML untuk pesan):

    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.")

### Menampilkan pesan

get_messages(request)

In your template, use something like:

    {% if messages %}
    <ul class="messages">
        {% for message in messages %}
        <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
        {% endfor %}
    </ul>
    {% endif %}

Jika anda sedang menggunakan pengolah konteks, cetakan anda harus dibangun dengan `RequestContext`. Sebaliknya, apstikan `messages` tersedia pada konteks cetakan.

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.

The context processor also provides a `DEFAULT_MESSAGE_LEVELS` variable which is a mapping of the message level names to their numeric value:

    {% 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 %}

Diluar Cetakan, anda dapat menggunakan `get_messages()`:

    from django.contrib.messages import get_messages

    storage = get_messages(request)
    for message in storage:
        do_something_with_the_message(message)

Sebagai contoh, anda dapat mengambil semua pesan-pesan untuk mengembalikan mereka di JSONResponseMixin daripada `TemplateResponseMixin`.

`get_messages()` akan mengembalikan sebuah instance dari backend penyimpanan dikonfigurasi

### Kelas `Message`

class 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`: Teks sebenarnya dari pesan.

  - `level`: Integer menggambarkan jenis dari pesan (lihat bagian message levels diatas).

  - `tags`: String memadukan semua etiket pesan (`extra_tags` dan `level_tag`) dipisahkan oleh ruang.

  - `extra_tags`: Sebuah string mengandung etiket-etiket penyesuaian untuk pesan ini, dipisahkan oleh ruang. Itu kosong secara awalan.

  - `level_tag`: Perwakilan string dari tingkatan. Secara awalan, itu adalah versi huruf kecil dari nama dari ketetapan terkait, tetapi ini dapat berubah jika anda butuh dengan menggunakanpengaturan `MESSAGE_TAGS`.

### Membuat penyesuaian tingkatan pesan

Tingkatan pesan tidak lebih dari integer, jadi anda dapat menentukan ketetapan tingkat anda sendiri dan menggunakan mereka membuat umpan balik pengguna penyesuaian lagi, misalnya:

    CRITICAL = 50

    def my_view(request):
        messages.add_message(request, CRITICAL, "A serious error occurred.")

Ketika membuat tingkatan-tingkatan pesan penyesuaian anda harus waspada menghindari tingkatan-tingkatan yang ada kelebihan beban. Nilai-nilai untuk tingkatan-tingkatan siap-pakai adalah:

Tingkat Ketetapan | Nilai
--- | ---
`DEBUG` | 10
`INFO` | 20
`BERHASIL` | 25
`PERINGATAN` | 30
`KESALAHAN` | 40

Jika anda buth mencirikan tingkatan penyesuaian dalam HTML atau CSS, anda butuh menyediakan sebuah pemetaan melalui pengaturan `MESSAGE_TAGS`.

Catatan

Jika anda sedang membuat aplikasi digunakan kembali, itu sangat dianjurkan untuk menggunakan hanya message levels siap-pakai dan jangan bergantung pada penyesuaian tingkat apapun

### Merubah tingkat terekam minimal per-permintaan

Tingkat terekam minimal dapat disetel per permintaan melalui metode `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)

Mirip, tingkat efektif saat ini dapat diambil dengan `get_level`:

    from django.contrib import messages

    current_level = messages.get_level(request)

Untuk informasi lebih pada bagaimana fungsi tingkat terekam minimal, lihat Message levels diatas.

### Menambahkan etiket pesan tambahan

Untuk lebih kendali langsung melalui etiket pesan, anda dapat secara pilihan menyediakan string mengandung etiket tambahan ke apapun dari metode tambah:

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

Etiket tambahan ditambahkan sebelum etiket awalan untuk tingkat itu dan ruang terpisah.

### Gagal secara diam ketika kerangka kerja pesan ditiadakan

Jika anda sedang menulis sebuah aplikasi digunakan kembali (atau potongan lain dari kode) dan ingin menyertakan kegunaan pesan, tetapi tidak ingin membutuhkan pengguna anda mengadakan itu jika mereka tidak ingin, anda mungkin melewatkan sebuah argumen kata kunci tambahan `fail_silently=True` ke apapun dari keluarga `add_message` dari metode-metode. Sebagai contoh:

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

Catatan

Mengatur `fail_silently=True` hanya menyembunyikan `MessageFailure` yang akan sebaliknya muncul ketika kerangka kerja pesan-pesan ditiadakan dan satu usaha untuk menggunakan satu dari keluarga `add_message` dari metode-metode. Itu tidak menyembunyikan kegagalan yang mungkin muncul untuk alasan-alasan lain.

### Menambahkan pesan-pesan di tampilan berdasarkan-kelas

class views.SuccessMessageMixin

  Menambah sebuah atribut pesan berhasil pada `FormView` berdasarkan kelas-kelas

  get_success_message(cleaned_data)

    `cleaned_data` adalah data dibersihkan dari formulir yang digunakan untuk pembentukan string

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

Data diberishkan dari `form` tersedia untuk penambahan string menggunakan sintaksis `%(field_name)s`. Untuk ModelForms, jika anda butuh mengakses ke bidang-bidang ini dari `object` tersimpan timpa metode `get_success_message()`.

Contoh views.py untuk 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,
            )

## Pesan berakhir

Pesan-pesan ditandai untuk dibersihkan ketika contoh penyimpanan diulangkan (dan dibersihkan ketika tanggapan diolah).

Untuk menghindari pesan-pesan sedang dibesihkan, anda dapat menyetel penyimpanan pesan-pesan menjadi `False` setelah perulangan:

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

## Perilaku dari permintaan paralel

Disebabkan oleh cara kue (dan karena itu sesi) bekerja, perilaku backend apapun yang menggunakan kue atau sesi tidak ditentukan ketika klien sama membuat banyak permintaan yang mensetel atau mendapatkan pesan-pesan sejajar. Sebagai contoh, jika sebuah klien memulai sebuah permintaan yang membuat sebuah pesan dalam satu jendela (atau tab) dan kemudian yang mengambil pesan-pesan apapun tidak berstatus di jendela lain, sebelum jendela pertama dialihkan, pesan mungkin muncul dalam jendela kedua darpada jendela pertama dimana itu mungkin diharapkan.

Ringkasnya, ketika permintaan-permintaan terus-menerus banyak dari klien sama dilibatkan, pesan-pesan tidak dijamin untuk dikirimkan ke jendela sama yang maupun membuat mereka, dalam beberapa kasus, sama sekali. Catat bahwa ini adalah khususnya bukan sebuah masalah dalam kebanyakan aplikasi dan akan menjadi bukan-masalah dalam HTML5, dimana setiap jendela/tab akan mempunyai konteks menjelajah milik sendiri.

## Pengaturan

Sedikit settings memberikan anda kendali terhadap perilaku pesan:

- `MESSAGE_LEVEL`

- `MESSAGE_STORAGE`

- `MESSAGE_TAGS`

Untuk backend yang menggunakan kue, pengaturan untuk kue diambil dari pengaturan kue sesi:

- `SESSION_COOKIE_DOMAIN`

- `SESSION_COOKIE_SECURE`

- `SESSION_COOKIE_HTTPONLY`

## Pengujian

This module offers a tailored test assertion method, for testing messages attached to an `HttpResponse`.

To benefit from this assertion, add `MessagesTestMixin` to the class hierarchy:

    from django.contrib.messages.test import MessagesTestMixin
    from django.test import TestCase

    class MsgTestCase(MessagesTestMixin, TestCase):
        pass

Then, inherit from the `MsgTestCase` in your tests.

MessagesTestMixin.assertMessages(response, expected_messages, ordered=True)

  Asserts that `messages` added to the `response` matches `expected_messages`.

  `expected_messages` is a list of `Message` objects.

  By default, the comparison is ordering dependent. You can disable this by setting the `ordered` argument to `False`.