# DEPRECATED: Django has cookie based messages since version 1.2 # # -*- coding: iso-8859-1 -*- # $Id: sessionutils.py 322 2009-04-22 10:53:04Z tguettler $ # $HeadURL: svn+ssh://svnserver/svn/djangotools/trunk/utils/sessionutils.py $ u''' http://www.djangosnippets.org/snippets/1459/ Modify the Session class of django. Create some extra methods. This way of hacking django is easier than running a modified version. MessageCookieMiddleware Usage: def view(request): if request.method=='POST': .... request.session.create_message(u'Your changes have been saved.') return django.http.ResponseRedirect(...) In the code or template where you create your HTML head, you need to insert: request.session.get_and_delete_messages() ''' # Python import os import sys import random from hashlib import sha1 import pickle # Django from django.utils.html import mark_safe from django.utils.html import conditional_escape as escape from django.utils.encoding import StrAndUnicode # Project from django.conf import settings KNOWN_LOGLEVELS=['info', 'error'] COOKIE_NAME='%s_messages' % (settings.SESSION_COOKIE_NAME) class MessageCookieMiddleware(object): def process_request(self, request): session=getattr(request, 'session', None) if session is None: return cookie=request.COOKIES.get(COOKIE_NAME) if cookie: session._messages=decode(cookie) else: session._messages=Messages() session._messages_modified=False def process_response(self, request, response): session=getattr(request, 'session', None) if session is None: return response messages=getattr(session, '_messages', None) if messages is None: return response if not session._messages_modified: return response if not messages: response.delete_cookie(COOKIE_NAME) else: response.set_cookie(COOKIE_NAME, encode(messages)) return response def get_messages(self): u'Normaly not needed. Use get_and_delete_messages()' messages=getattr(self, '_messages', None) if messages is None: raise AttributeError('session has no attribute _messages. MessageCookieMiddleware in settings.MIDDLEWARE_CLASSES?') return messages def get_and_delete_messages(self): messages=self.get_messages() if messages: messages=Messages(messages) # copy self._messages=Messages() self._messages_modified=True return messages class Messages(list, StrAndUnicode): def __unicode__(self): if not self: return u'' return mark_safe(u'' % u''.join([unicode(m) for m in self])) def __repr__(self): return '<%s object %s messages: %s>' % (self.__class__.__name__, len(self), u'; '.join([m.message for m in self])) class Message(object): def __init__(self, message, loglevel='info'): self.message=message assert loglevel in KNOWN_LOGLEVELS, loglevel self.loglevel=loglevel def __unicode__(self): return mark_safe(u'
  • %s
  • ' % (self.loglevel, escape(self.message))) def create_message(self, message, loglevel='info'): messages=self.get_messages() messages.append(Message(message, loglevel)) self._messages_modified = True # encode and decode based on from http://www.djangosnippets.org/snippets/1064/ def encode(value): assert value value = pickle.dumps(value) hash = sha1(value + settings.SECRET_KEY) return '%s$%s' % (hash.hexdigest(), value) def decode(cookie): u''' unpickling of untrusted data is dangerous. Uses settings.SECRET_KEY to create a sha1 signature. ''' assert cookie s = cookie.split('$', 1) hash, value = s should = sha1(value + settings.SECRET_KEY).hexdigest() if should != hash: raise Exception('verify of sha1 signed cookie failed. should!=hash (%s!=%s)' % ( should, hash)) return pickle.loads(value) def get_dir(self): session_dir=os.path.join(settings.MEDIA_ROOT, 'sessions', self.session_key) if not os.path.exists(session_dir): os.mkdir(session_dir) return session_dir def get_tempfile(self, extension='', basename=None): u''' extensions: txt, png, pdf, ... ''' if not basename: if extension: dot='.' else: dot='' basename='%s%s%s' % (random.randint(0, sys.maxint), dot, extension) path=os.path.join(self.get_dir(), basename) url='%ssessions/%s/%s' % (settings.MEDIA_URL, self.session_key, basename) return (path, url) # Start Hacking Django from django.contrib.sessions.backends.base import SessionBase SessionBase.get_messages=get_messages SessionBase.get_and_delete_messages=get_and_delete_messages SessionBase.create_message=create_message SessionBase.get_dir=get_dir SessionBase.get_tempfile=get_tempfile # End Hacking Django