I often show messages about user actions to logged in users in my Django app views using:
request.user.message_set.create("message to user")
How could I do the same for anonymous (not logged in) users? There is no request.user for anonymous users, but the Django documentation says that using the "session" middleware you can do the same thing as the above code. The Django documentation that links to the session middleware claims it is possible, but I couldn't find how to do it from the session documentation.
Django uses a cookie containing a special session id to identify each browser and its associated session with the site. The actual session data is stored in the site database by default (this is more secure than storing the data in a cookie, where they are more vulnerable to malicious users).
As of Django 1.8, any call to flush() will log out the user. From the docs: Changed in Django 1.8: Deletion of the session cookie is a behavior new in Django 1.8. Previously, the behavior was to regenerate the session key value that was sent back to the user in the cookie.
This is what I do, using context processors:
project/application/context.py
(check for messages and add them to the context):
def messages(request):
messages = {}
if 'message' in request.session:
message_type = request.session.get('message_type', 'error')
messages = {'message': request.session['message'],
'message_type': message_type}
del request.session['message']
if 'message_type' in request.session:
del request.session['message_type']
return messages
project/settings.py
(add the context to the TEMPLATE_CONTEXT_PROCESSORS
):
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.request",
"django.core.context_processors.debug",
"django.core.context_processors.media",
"django.core.context_processors.auth",
"project.application.context.messages",
)
With the above the function messages
will be called on every request and whatever it returns will be added to the template's context. With this in place, if I want to give a user a message, I can do this:
def my_view(request):
if someCondition:
request.session['message'] = 'Some Error Message'
Finally, in a template you can just check if there are errors to display:
{% if message %}
<div id="system_message" class="{{ message_type }}">
{{ message }}
</div>
{% endif %}
The message type is just used to style depending on what it is ("error","notice","success") and the way that this is setup you can only add 1 message at a time for a user, but that is all I really ever need so it works for me. It could be easily changed to allow for multiple messages and such.
See http://code.google.com/p/django-session-messages/ until the patch that enables session based messages lands in Django tree (as I saw recently, it's marked for 1.2, so no hope for quick addition...).
Another project with similar functionality is Django Flash (http://djangoflash.destaquenet.com/).
Store the data directly in the session, which is a dict-like object. Then in the view/template, check for the value.
More information here:
http://docs.djangoproject.com/en/dev/topics/http/sessions/#using-sessions-in-views
You could also create a middleware class to check for the session object on each request, and do your build up/tear down there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With