Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send a session message to an anonymous user in a Django site?

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.

like image 534
MikeN Avatar asked Mar 30 '09 16:03

MikeN


People also ask

Where is session data typically stored in a Django application?

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

How do I end a session in Django?

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.


3 Answers

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.

like image 69
Paolo Bergantino Avatar answered Oct 30 '22 21:10

Paolo Bergantino


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

like image 26
zgoda Avatar answered Oct 30 '22 21:10

zgoda


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.

like image 4
Daniel Naab Avatar answered Oct 30 '22 20:10

Daniel Naab