The Messages Framework

Django's messages framework is a built-in system for showing one-time "flash" notifications — short status messages like "Profile saved!" or "Login failed" that appear once after an action and then disappear, surviving the redirect that usually follows a form submission.

Learn The Messages Framework in our free Django course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Django course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll learn how to add messages with messages.success() , messages.error() , messages.info() , and messages.warning() , how to display them in a template, and how message tags let you style each level differently.

The messages framework lets a view attach a short notification to the current request. You import django.contrib.messages as messages and call one of its level methods, passing the request and the text to show.

The most common pattern is "do something, add a message, then redirect." Because the message is stored between the redirect and the next page, the user reliably sees it even though they land on a brand-new request.

Once a view has added messages, your template displays them by looping over the messages variable that Django's context processor makes available. Each message has a tags attribute (like success or error ) you can drop straight into a CSS class.

Here alert-{'{ message.tags }'} renders to something like alert-success or alert-error , letting you give each severity its own colour. Messages are consumed once read, so they appear exactly once and then vanish.

Django provides five severity levels, each with its own convenience method and default tag. Choosing the right one tells the user how important a notification is and lets your CSS colour it appropriately.

If your CSS framework expects different class names (for example Bootstrap uses danger instead of error ), you can remap the tags in settings.py with MESSAGE_TAGS .

Fill in the blank with the correct messages method so a successful save shows a green success notification.

❌ Messages added but nothing shows on the page

Your template never loops over the messages variable.

✅ Fix: add a {' '} loop to your base template.

❌ MessageFailure: You cannot add messages without...

The message middleware or context processor is missing.

✅ Fix: ensure django.contrib.messages is in INSTALLED_APPS and its middleware is enabled.

You rendered the messages list more than once on the page.

✅ Fix: loop over messages in exactly one place, usually the base template.

Write a function that adds the right message for each checkout outcome: success when paid, warning when low stock, and error when the card is declined.

Lesson complete — you can flash messages to your users!

You now know how to add messages with the level methods, display them in a template by looping over messages , and style each level using its tag or a custom MESSAGE_TAGS mapping.

🚀 Up next: User Authentication — log users in and out, and protect views with login_required.

Practice quiz

What is the messages framework mainly used for?

  • Storing user passwords
  • One-time flash notifications shown on the next page
  • Sending email
  • Caching query results

Answer: One-time flash notifications shown on the next page. It attaches one-time notifications that survive a redirect.

How many built-in message levels does Django provide?

  • Three
  • Four
  • Five
  • Six

Answer: Five. debug, info, success, warning, and error are the five levels.

Which call adds a success-level message?

  • messages.ok(request, text)
  • messages.success(request, text)
  • messages.add('success', text)
  • messages.green(request, text)

Answer: messages.success(request, text). messages.success(request, text) adds a success message.

What attribute on a message gives a CSS-friendly tag like 'success'?

  • message.level
  • message.css
  • message.tags
  • message.style

Answer: message.tags. message.tags yields a tag string derived from the level.

How are messages shown in a template?

  • By calling messages.render()
  • By looping over the messages variable
  • Automatically in every response
  • With a context processor only

Answer: By looping over the messages variable. You loop over the messages variable, e.g. {% for message in messages %}.

What happens to a message once it has been read/rendered?

  • It is consumed and disappears
  • It persists forever
  • It is emailed to the user
  • It is saved to the database permanently

Answer: It is consumed and disappears. Messages are consumed once read, so they appear exactly once.

Which setting remaps message levels to custom CSS classes?

  • MESSAGE_LEVELS
  • MESSAGE_CLASSES
  • TAGS
  • MESSAGE_TAGS

Answer: MESSAGE_TAGS. MESSAGE_TAGS in settings.py remaps levels to your own class names.

Why is the common pattern 'add a message, then redirect'?

  • Redirects are faster
  • The message survives the redirect via Post/Redirect/Get
  • Messages require a redirect to be created
  • It clears the database

Answer: The message survives the redirect via Post/Redirect/Get. The message is stored across the redirect so the user reliably sees it.

Which level signals that an action failed?

  • messages.info()
  • messages.warning()
  • messages.error()
  • messages.success()

Answer: messages.error(). messages.error() indicates an action failed.

If messages are added but nothing shows, what is the most common cause?

  • The template never loops over the messages variable
  • The database is offline
  • The user is logged out
  • Django is too old

Answer: The template never loops over the messages variable. Usually the template is missing the loop over messages.