Sessions, Cookies & Messages
Remember things between requests with sessions and cookies, and show one-off flash messages like “Saved!” after an action.
What you will learn
- Explain cookies vs sessions
- Store and read data in request.session
- Show flash messages with the messages framework
The web forgets — so we help it remember
HTTP is stateless: each request stands alone, and the server forgets you the instant it replies. To remember anything between pages — that you are logged in, what is in your cart — we use two tools that work together.
| Cookie | Session | |
|---|---|---|
| Lives | in the browser | on the server |
| Holds | a small bit of text (often an id) | the real data, keyed by that id |
| Safe for secrets? | no — user can read it | yes — server-side |
A cookie is a small piece of text the server asks the browser to store and send back on every future request. A session is server-side storage tied to a visitor; Django puts only a random session id in a cookie, and keeps the actual data safely on the server. This is exactly how login remembered the user in the auth lesson.
Using the session
Django gives every request a request.session object that behaves like a Python dictionary — but its contents survive across requests. A classic use is a simple "items in cart" counter:
def add_to_cart(request, product_id):
cart = request.session.get("cart", []) # read (default: empty list)
cart.append(product_id)
request.session["cart"] = cart # write it back
return redirect("cart")
def cart(request):
cart = request.session.get("cart", [])
return render(request, "cart.html", {"count": len(cart)})Line by line: request.session.get("cart", []) reads the saved cart, defaulting to an empty list the first time. We append the new product id, then assign it back to request.session["cart"] — that assignment is what saves it. On the next page, the same key returns the stored list, so the cart "remembers" across requests.
Note: Output: the user adds two products on two separate clicks, then visits the cart page and sees count: 2 — even though each click was a separate request. The session carried the data across.
The messages framework — flash messages
After an action you often want a one-time notice: "Post saved!", "Wrong password". The messages framework shows a message once on the next page, then forgets it (a "flash message"). You add a message in the view and render any pending ones in the template:
# views.py
from django.contrib import messages
def save_post(request):
# ... save the post ...
messages.success(request, "Post saved!")
return redirect("post_list")<!-- in the template (e.g. base.html) -->
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li class="{{ message.tags }}">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}The message levels match common notice types: messages.success, messages.error, messages.warning and messages.info. The {{ message.tags }} gives you a CSS class (like success or error) so you can colour each one.
Note: Output: after saving, the user is redirected to the list and sees a green "Post saved!" banner once. Refreshing the page makes it disappear — that is the "flash" behaviour.
Tip: Sessions are perfect for carts, "recently viewed" and multi-step forms. Use the messages framework for any "it worked / it failed" notice after a redirect — it is the standard Django way.
Q. Where does Django store the actual session data, and what goes in the cookie?
✍️ Practice
- Build a tiny cart using
request.sessionthat counts added items across requests. - Add a
messages.successafter saving a record and render the messages in your base template.
🏠 Homework
- Add success/error flash messages to every create, update and delete action in your app.