# Django 6.0.5 documentation

# Ramverket för meddelanden

I webbapplikationer är det vanligt att du behöver visa ett engångsmeddelande (även kallat ”flashmeddelande”) till användaren efter att ha bearbetat ett formulär eller någon annan typ av användarinmatning.

För detta ger Django fullt stöd för cookie- och sessionsbaserad meddelandehantering, för både anonyma och autentiserade användare. Med meddelanderamen kan du tillfälligt lagra meddelanden i en begäran och hämta dem för visning i en efterföljande begäran (vanligtvis nästa). Varje meddelande är taggat med en specifik ”nivå” som bestämmer dess prioritet (t.ex. ”info”, ”varning” eller ”fel”).

## Aktivering av meddelanden

Meddelanden implementeras genom en middleware-klass och motsvarande context processor.

Standardinställningen `settings.py` som skapats av `django-admin startproject` innehåller redan alla inställningar som krävs för att aktivera meddelandefunktionen:

- `'django.contrib.messages'` finns i `INSTALLED_APPS`.

- `MIDDLEWARE` innehåller `'django.contrib.sessions.middleware.SessionMiddleware'` och `'django.contrib.messages.middleware.MessageMiddleware'`.

  Standard storage backend förlitar sig på sessions. Det är därför `SessionMiddleware` måste vara aktiverat och visas före `MessageMiddleware` i `MIDDLEWARE`.

- Alternativet `'context_processors'` för backend `DjangoTemplates` som definieras i din `TEMPLATES`-inställning innehåller `'django.contrib.messages.context_processors.messages'`.

Om du inte vill använda meddelanden kan du ta bort `'django.contrib.messages'` från din `INSTALLED_APPS`, raden `MessageMiddleware` från `MIDDLEWARE` och kontextprocessorn `messages` från `TEMPLATES`.

## Konfigurera meddelandemotorn

### Backend för lagring

Meddelanderamen kan använda olika backends för att lagra tillfälliga meddelanden.

Django tillhandahåller tre inbyggda lagringsklasser i `django.contrib.messages`:

class storage.session.SessionStorage

  Den här klassen lagrar alla meddelanden i begäran om session. Därför kräver den Djangos `contrib.sessions` applikation.

class storage.cookie.CookieStorage

  Denna klass lagrar meddelandedata i en cookie (signerad med en hemlig hash för att förhindra manipulation) för att hålla kvar meddelanden över förfrågningar. Gamla meddelanden tas bort om cookiedatastorleken skulle överstiga 2048 byte.

class storage.fallback.FallbackStorage

  Denna klass använder först `CookieStorage`, och faller tillbaka till att använda `SessionStorage` för de meddelanden som inte kunde rymmas i en enda cookie. Den kräver också Djangos applikation `contrib.sessions`.

  Detta beteende undviker att skriva till sessionen när det är möjligt. Det bör ge bäst prestanda i det allmänna fallet.

`FallbackStorage` är standardlagringsklassen. Om den inte är lämplig för dina behov kan du välja en annan lagringsklass genom att ange `MESSAGE_STORAGE` till dess fullständiga importsökväg, till exempel:

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

class storage.base.BaseStorage

För att skriva din egen lagringsklass, subklassa klassen `BaseStorage` i `django.contrib.messages.storage.base` och implementera metoderna `_get` och `_store`.

### Meddelandenivåer

Meddelanderamen bygger på en konfigurerbar nivåarkitektur som liknar den i Pythons loggmodul. Med meddelandenivåer kan du gruppera meddelanden efter typ så att de kan filtreras eller visas på olika sätt i vyer och mallar.

De inbyggda nivåerna, som kan importeras direkt från `django.contrib.messages`, är:

Konstant | Syfte
--- | ---
`DEBUG` | Utvecklingsrelaterade meddelanden som kommer att ignoreras (eller tas bort) i en produktionsdistribution
`INFO` | Informationsmeddelanden för användaren
`SUCCESS` | En åtgärd lyckades, t.ex. ”Din profil uppdaterades framgångsrikt”
”VARNING | Ett fel inträffade inte men kan vara nära förestående
`ERROR` | En åtgärd lyckades inte eller något annat fel inträffade

Inställningen `MESSAGE_LEVEL` kan användas för att ändra den lägsta inspelade nivån (eller så kan den ändras på begäran). Försök att lägga till meddelanden på en lägre nivå än denna ignoreras.

### Taggar för meddelanden

Meddelandetaggar är en strängrepresentation av meddelandenivån plus eventuella extra taggar som har lagts till direkt i vyn (se ”Lägga till extra meddelandetaggar” nedan för mer information). Taggarna lagras i en sträng och separeras med mellanslag. Meddelandetaggar används vanligtvis som CSS-klasser för att anpassa meddelandestilen baserat på meddelandetyp. Som standard har varje nivå en enda tagg som är en gemen version av sin egen konstant:

Nivå Konstant | Tagg
--- | ---
`DEBUG` | `debug`
`INFO` | `info`
`SUCCESS` | `framgång`
”VARNING | `varning`
`ERROR` | `fel`

Om du vill ändra standardtaggarna för en meddelandenivå (antingen inbyggd eller anpassad) anger du inställningen `MESSAGE_TAGS` till en ordbok som innehåller de nivåer du vill ändra. Eftersom detta utökar standardtaggarna behöver du bara ange taggar för de nivåer som du vill åsidosätta:

    from django.contrib.messages import constants as messages

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

## Använda meddelanden i vyer och mallar

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

### Lägga till ett meddelande

För att lägga till ett meddelande, ring:

    from django.contrib import messages

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

Vissa genvägsmetoder ger ett standardiserat sätt att lägga till meddelanden med vanligt förekommande taggar (som vanligtvis representeras som HTML-klasser för meddelandet):

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

### Visning av meddelanden

get_messages(request)

I din mall, använd något liknande:

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

Om du använder kontextprocessorn bör din mall återges med en `RequestContext`. Annars ska du se till att `messages` är tillgängligt för mallkontexten.

Även om du vet att det bara finns ett meddelande bör du ändå iterera över sekvensen `messages`, eftersom meddelandelagret annars inte kommer att rensas för nästa begäran.

Kontextprocessorn tillhandahåller också variabeln `DEFAULT_MESSAGE_LEVELS` som är en mappning av meddelandenivåernas namn till deras numeriska värde:

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

Utanför mallar kan du använda `get_messages()`:

    from django.contrib.messages import get_messages

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

Du kan till exempel hämta alla meddelanden för att returnera dem i en JSONResponseMixin istället för en `TemplateResponseMixin`.

`get_messages()` kommer att returnera en instans av den konfigurerade lagringsbackend.

### Klassen `Message` (meddelande)

class Message

  När man loopar över listan med meddelanden i en mall får man fram instanser av klassen `Message`. De har bara ett fåtal attribut:

  - `meddelande`: Den faktiska texten i meddelandet.

  - `nivå`: Ett heltal som beskriver typen av meddelande (se avsnittet meddelandenivåer ovan).

  - `tags`: En sträng som kombinerar alla meddelandets taggar (`extra_tags` och `level_tag`) separerade med mellanslag.

  - `extra_tags`: En sträng som innehåller anpassade taggar för detta meddelande, separerade med mellanslag. Den är tom som standard.

  - `level_tag`: Strängrepresentationen av nivån. Som standard är det den gemena versionen av namnet på den associerade konstanten, men detta kan ändras om du behöver genom att använda inställningen `MESSAGE_TAGS`.

### Skapa anpassade meddelandenivåer

Meddelandenivåerna är inget annat än heltal, så du kan definiera dina egna nivåkonstanter och använda dem för att skapa mer anpassad användaråterkoppling, t.ex:

    CRITICAL = 50

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

När du skapar egna meddelandenivåer bör du vara försiktig så att du inte överbelastar befintliga nivåer. Värdena för de inbyggda nivåerna är:

Nivå Konstant | Värde
--- | ---
`DEBUG` | 10
`INFO` | 20
`SUCCESS` | 25
”VARNING | 30
`ERROR` | 40

Om du behöver identifiera de anpassade nivåerna i din HTML eller CSS måste du tillhandahålla en mappning via inställningen `MESSAGE_TAGS`.

Observera

Om du skapar en återanvändbar applikation rekommenderas att du endast använder de inbyggda message levels och inte förlitar dig på några anpassade nivåer.

### Ändring av lägsta inspelade nivå per förfrågan

Den lägsta registrerade nivån kan ställas in per begäran via metoden `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)

På samma sätt kan den aktuella effektiva nivån hämtas med `get_level`:

    from django.contrib import messages

    current_level = messages.get_level(request)

För mer information om hur den lägsta inspelningsnivån fungerar, se Meddelandenivåer ovan.

### Lägga till extra meddelandetaggar

Om du vill ha mer direkt kontroll över meddelandetaggar kan du ange en sträng med extra taggar till någon av add-metoderna:

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

Extra taggar läggs till före standardtaggen för den aktuella nivån och är mellanslagsseparerade.

### Misslyckas i tysthet när meddelanderamen är inaktiverad

Om du skriver en återanvändbar app (eller annan kod) och vill inkludera meddelandefunktionalitet, men inte vill kräva att dina användare aktiverar det om de inte vill, kan du skicka ett ytterligare nyckelordsargument `fail_silently=True` till någon av metoderna i `add_message`-familjen. Till exempel:

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

Observera

Om du ställer in `fail_silently=True` döljs bara `MessageFailure` som annars skulle inträffa när meddelanderamen inaktiveras och man försöker använda en av metoderna i `add_message`-familjen. Den döljer inte fel som kan uppstå av andra skäl.

### Lägga till meddelanden i klassbaserade vyer

class views.SuccessMessageMixin

  Lägger till ett attribut för framgångsmeddelande till `FormView`-baserade klasser

  get_success_message(cleaned_data)

    `cleaned_data` är de rensade data från formuläret som används för strängformatering

Exempel på 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"

De rensade uppgifterna från `formuläret` är tillgängliga för stränginterpolering med syntaxen `%(field_name)s`. För ModelForms, om du behöver tillgång till fält från det sparade `objektet` åsidosätt metoden `get_success_message()`.

Exempel på views.py för 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,
            )

## Utgång av meddelanden

Meddelandena markeras för att rensas när lagringsinstansen itereras (och rensas när svaret bearbetas).

För att undvika att meddelandena rensas kan du ställa in meddelandelagringen till `False` efter iteration:

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

## Beteende för parallella förfrågningar

På grund av hur cookies (och därmed sessioner) fungerar, är beteendet hos alla backends som använder cookies eller sessioner odefinierat när samma klient gör flera begäranden som ställer in eller hämtar meddelanden parallellt. Om en klient t.ex. initierar en begäran som skapar ett meddelande i ett fönster (eller en flik) och sedan en annan som hämtar alla oitererade meddelanden i ett annat fönster, innan det första fönstret omdirigeras, kan meddelandet visas i det andra fönstret i stället för i det första fönstret där det kan förväntas.

Kort sagt, när flera samtidiga förfrågningar från samma klient är inblandade, är det inte garanterat att meddelanden levereras till samma fönster som skapade dem eller, i vissa fall, inte alls. Observera att detta normalt inte är ett problem i de flesta tillämpningar och att det kommer att bli ett icke-problem i HTML5, där varje fönster/flik kommer att ha sin egen webbläsarkontext.

## Inställningar

Några inställningar ger dig kontroll över meddelandets beteende:

- `MESSAGE_LEVEL`

- `MESSAGE_STORAGE`

- `MESSAGE_TAGS`

För backends som använder cookies hämtas inställningarna för cookien från inställningarna för sessionscookien:

- `SESSION_COOKIE_DOMAIN`

- `SESSION_COOKIE_SECURE`

- `SESSION_COOKIE_HTTPONLY`

## Testar

Denna modul erbjuder en skräddarsydd testmetod för att testa meddelanden som är kopplade till en `HttpResponse`.

För att dra nytta av denna försäkran, lägg till `MessagesTestMixin` i klasshierarkin:

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

    class MsgTestCase(MessagesTestMixin, TestCase):
        pass

Ärv sedan från `MsgTestCase` i dina tester.

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

  Säkerställer att `messages` som lagts till i `response` matchar `expected_messages`.

  `expected_messages` är en lista med `Message`-objekt.

  Som standard är jämförelsen beroende av ordningsföljd. Du kan inaktivera detta genom att ställa in argumentet `ordered` till `False`.