Ticket #4604: messages.7.diff
File messages.7.diff, 15.5 KB (added by , 17 years ago) |
---|
-
django/core/context_processors.py
8 8 """ 9 9 10 10 from django.conf import settings 11 from django.utils.encoding import StrAndUnicode 11 12 12 13 def auth(request): 13 14 """ … … 22 23 else: 23 24 from django.contrib.auth.models import AnonymousUser 24 25 user = AnonymousUser() 25 return{26 context_extras = { 26 27 'user': user, 27 'messages': user.get_and_delete_messages(),28 28 'perms': PermWrapper(user), 29 29 } 30 # Add authentication (and session) LazyMessages to the context too. 31 context_extras.update(messages(request)) 32 return context_extras 30 33 34 def messages(request): 35 """ 36 Returns messages for the session and the current user. 37 38 Note that this processor is only useful to use explicity if you are not 39 using the (enabled by default) auth processor, as it also provides the 40 messages (by calling this method). 41 42 The messages are lazy loaded, so no messages are retreived and deleted 43 unless requested from the template. 44 45 Both contrib.session and contrib.auth are optional. If neither is provided, 46 no 'messages' variable will be added to the context. 47 """ 48 if hasattr(request, 'session') or hasattr(request, 'user'): 49 return {'messages': LazyMessages(request)} 50 return {} 51 31 52 def debug(request): 32 53 "Returns context variables helpful for debugging." 33 54 context_extras = {} … … 82 103 83 104 def __getitem__(self, module_name): 84 105 return PermLookupDict(self.user, module_name) 106 107 # LazyMessages is used by the `messages` and `auth` context processors. 108 109 class LazyMessages(StrAndUnicode): 110 """ 111 A lazy proxy for session and authentication messages. 112 """ 113 def __init__(self, request): 114 self.request = request 115 116 def __iter__(self): 117 return iter(self.messages) 118 119 def __len__(self): 120 return len(self.messages) 121 122 def __nonzero__(self): 123 return bool(self.messages) 124 125 def __unicode__(self): 126 return unicode(self.messages) 127 128 def __getitem__(self, *args, **kwargs): 129 return self.messages.__getitem__(*args, **kwargs) 130 131 def _get_messages(self): 132 if hasattr(self, '_messages'): 133 return self._messages 134 # First, retreive any messages for the user. 135 if hasattr(self.request, 'user') and \ 136 hasattr(self.request.user, 'get_and_delete_messages'): 137 self._messages = self.request.user.get_and_delete_messages() 138 else: 139 self._messages = [] 140 # Next, retrieve any messages for the session. 141 if hasattr(self.request, 'session'): 142 self._messages += self.request.session.get_and_delete_messages() 143 return self._messages 144 messages = property(_get_messages) -
django/contrib/sessions/tests.py
16 16 'dog' 17 17 >>> db_session.pop('some key', 'does not exist') 18 18 'does not exist' 19 >>> db_session.get_messages() 20 [] 21 >>> db_session.create_message('first post') 22 >>> db_session.get_messages() 23 ['first post'] 24 >>> db_session.get_and_delete_messages() 25 ['first post'] 26 >>> db_session.get_and_delete_messages() 27 [] 28 >>> db_session.create_message('hello') 29 >>> db_session.create_message('world') 30 >>> db_session.get_and_delete_messages() 31 ['hello', 'world'] 19 32 >>> db_session.save() 20 33 >>> db_session.exists(db_session.session_key) 21 34 True … … 33 46 'dog' 34 47 >>> file_session.pop('some key', 'does not exist') 35 48 'does not exist' 49 >>> file_session.get_messages() 50 [] 51 >>> file_session.create_message('first post') 52 >>> file_session.get_messages() 53 ['first post'] 54 >>> file_session.get_and_delete_messages() 55 ['first post'] 56 >>> file_session.get_and_delete_messages() 57 [] 58 >>> file_session.create_message('hello') 59 >>> file_session.create_message('world') 60 >>> file_session.get_and_delete_messages() 61 ['hello', 'world'] 36 62 >>> file_session.save() 37 63 >>> file_session.exists(file_session.session_key) 38 64 True … … 57 83 'dog' 58 84 >>> cache_session.pop('some key', 'does not exist') 59 85 'does not exist' 86 >>> cache_session.get_messages() 87 [] 88 >>> cache_session.create_message('first post') 89 >>> cache_session.get_messages() 90 ['first post'] 91 >>> cache_session.get_and_delete_messages() 92 ['first post'] 93 >>> cache_session.get_and_delete_messages() 94 [] 95 >>> cache_session.create_message('hello') 96 >>> cache_session.create_message('world') 97 >>> cache_session.get_and_delete_messages() 98 ['hello', 'world'] 60 99 >>> cache_session.save() 61 100 >>> cache_session.delete(cache_session.session_key) 62 101 >>> cache_session.exists(cache_session.session_key) -
django/contrib/sessions/backends/base.py
18 18 """ 19 19 TEST_COOKIE_NAME = 'testcookie' 20 20 TEST_COOKIE_VALUE = 'worked' 21 MESSAGES_NAME = '_messages' 21 22 22 23 def __init__(self, session_key=None): 23 24 self._session_key = session_key … … 68 69 def delete_test_cookie(self): 69 70 del self[self.TEST_COOKIE_NAME] 70 71 72 def get_messages(self): 73 return self.get(self.MESSAGES_NAME, []) 74 75 def get_and_delete_messages(self): 76 return self.pop(self.MESSAGES_NAME, []) 77 78 def create_message(self, message): 79 messages = self.get(self.MESSAGES_NAME) 80 if messages is None: 81 messages = [] 82 self[self.MESSAGES_NAME] = messages 83 messages.append(message) 84 self.modified = True 85 71 86 def encode(self, session_dict): 72 87 "Returns the given session dictionary pickled and encoded as a string." 73 88 pickled = pickle.dumps(session_dict, pickle.HIGHEST_PROTOCOL) -
tests/regressiontests/messages/tests.py
1 """ 2 >>> from django.core import context_processors 3 >>> from django.http import HttpRequest 4 5 Set up request with a fake user and session (just enough to test getting and 6 deleting messages). 7 >>> request = HttpRequest() 8 >>> class FakeMessageObj: 9 ... def __init__(self, object, messages): 10 ... self.messages = messages 11 ... self.object = object 12 ... def get_and_delete_messages(self): 13 ... print 'Getting and deleting any %s messages...' % self.object 14 ... m = self.messages 15 ... self.messages = [] 16 ... return m 17 >>> request.user = FakeMessageObj('user', ['User message']) 18 >>> request.session = FakeMessageObj('session', ['Message 1', 'Second message']) 19 20 Run the messages context processor, and pull out the messages context variable. 21 >>> context = context_processors.messages(request) 22 >>> messages = context['messages'] 23 24 The messages context variable is a LazyMessages class. The messages haven't 25 actually been retreived (and deleted) yet. 26 >>> messages.__class__ 27 <class 'django.core.context_processors.LazyMessages'> 28 29 When any of the following methods are called, the messages are retreived from 30 the session (and user if contrib.auth is installed) from the LazyMessages 31 object to be retreived: __iter__, __len__, __nonzero__, __unicode__, 32 __getitem__ 33 >>> len(messages) 34 Getting and deleting any user messages... 35 Getting and deleting any session messages... 36 3 37 38 When messages are retreived, messages are deleted from the session (and user if 39 contrib.auth is installed). 40 >>> request.user.messages 41 [] 42 >>> request.session.messages 43 [] 44 45 The messages are still available to the LazyMessages instance because it caches 46 them. 47 >>> for message in messages: 48 ... print message 49 User message 50 Message 1 51 Second message 52 >>> messages[-1] 53 'Second message' 54 55 Both contrib.sessions and contrib.auth are optional. If neither are provided, 56 no 'messages' variable will be added to the context. 57 >>> del request.user 58 >>> request.session = FakeMessageObj('session', []) 59 >>> context = context_processors.messages(request) 60 >>> messages = context['messages'] 61 >>> if messages: 62 ... print 'messages found!' 63 Getting and deleting any session messages... 64 65 >>> del request.session 66 >>> request.user = FakeMessageObj('user', []) 67 >>> context = context_processors.messages(request) 68 >>> messages = context['messages'] 69 >>> if messages: 70 ... print 'messages found!' 71 Getting and deleting any user messages... 72 73 >>> del request.user 74 >>> context = context_processors.messages(request) 75 >>> context 76 {} 77 """ -
docs/sessions.txt
193 193 request.session.set_test_cookie() 194 194 return render_to_response('foo/login_form.html') 195 195 196 Messages 197 ======== 198 199 **New in Django development version** 200 201 The session message system provides a simple way to queue messages for all 202 (anonymous or authenticated) site visitors. To associate messages with users in 203 the user database, use the `authentication message framework`_. 204 205 .. _authentication message framework: ../authentication/#messages 206 207 Messages are associated with a session, therefore a message only lasts as long 208 as a session is valid (see `browser-length sessions vs. persistent sessions`_). 209 210 The message system relies on the session middleware and is accessed via 211 ``request.session``. The API is simple: 212 213 * To create a new message, use 214 ``request.session.create_message(message='message text').`` 215 216 * To retreive the messages, use ``request.session.get_messages()``, 217 which returns a list of any messages (strings) in the session's queue. 218 219 * To retrieve and delete messages, use 220 ``request.session.get_and_delete_messages()``, which returns the list of 221 any messages in the session's queue and then deletes the messages from the 222 queue. 223 224 The `django.core.context_processors.messages`_ context processor makes both 225 session messages and user messages available to templates. 226 227 .. _django.core.context_processors.messages: ../templates_python/#django-core-context_processors-messages 228 196 229 Using sessions out of views 197 230 =========================== 198 231 -
docs/authentication.txt
956 956 Messages 957 957 ======== 958 958 959 The message system is a lightweight way to queue messages for given users. 959 The user message system is a lightweight way to queue messages for given users. 960 To send messages to anonymous users, use `session messages`_. 960 961 962 .. _session framework: ../sessions/#messages 963 961 964 A message is associated with a ``User``. There's no concept of expiration or 962 965 timestamps. 963 966 … … 983 986 context_instance=RequestContext(request)) 984 987 985 988 When you use ``RequestContext``, the currently logged-in user and his/her 986 messages are made available in the `template context`_ as the template variable987 ``{{ messages }}``. Here's an example of template code that displays messages:: 989 messages are made available in the `template context`_ as the ``{{ messages }}`` 990 template variable. 988 991 989 {% if messages %} 990 <ul> 991 {% for message in messages %} 992 <li>{{ message }}</li> 993 {% endfor %} 994 </ul> 995 {% endif %} 992 **New in Django development version** 996 993 997 Note that ``RequestContext`` calls ``get_and_delete_messages`` behind the 998 scenes, so any messages will be deleted even if you don't display them.994 The ``{{ messages }}`` template variable will also contain session messages. 995 For more information, see `django.core.context_processors.messages`_. 999 996 1000 Finally, note that this messages framework only works with users in the user 1001 database. To send messages to anonymous users, use the `session framework`_. 997 .. _django.core.context_processors.messages: ../templates_python/#django-core-context_processors-messages 1002 998 1003 .. _session framework: ../sessions/ 999 Also note that previously, ``RequestContext`` directly called 1000 ``get_and_delete_messages`` behind the scenes, so any messages were deleted even 1001 if not displayed. Messages are now only deleted if the ``{{ messages }}`` 1002 variable is accessed in a template. 1004 1003 1005 1004 Other authentication sources 1006 1005 ============================ -
docs/templates_python.txt
346 346 logged in). See the `user authentication docs`_. 347 347 348 348 * ``messages`` -- A list of messages (as strings) for the currently 349 logged-in user. Behind the scenes, this calls 350 ``request.user.get_and_delete_messages()`` for every request. That method 351 collects the user's messages and deletes them from the database. 349 logged-in user. 352 350 353 Note that messages are set with ``user.message_set.create``. See the 354 `message docs`_ for more. 351 **New in Django development version** 355 352 353 This ``messages`` list now also contains session messages. 354 355 The messages are not retrieved and cleared (using 356 ``get_and_delete_messages``) until the ``messages`` variable is accessed 357 in a template whereas previously, this context processor called 358 ``request.user.get_and_delete_messages()`` behind the scenes for every 359 request. 360 361 See the `authentication message docs`_ or `session message docs`_ for 362 information on creating messages. 363 356 364 * ``perms`` -- An instance of 357 365 ``django.core.context_processors.PermWrapper``, representing the 358 366 permissions that the currently logged-in user has. See the `permissions 359 367 docs`_. 360 368 361 369 .. _user authentication docs: ../authentication/#users 362 .. _message docs: ../authentication/#messages 370 .. _authentication message docs: ../authentication/#messages 371 .. _session message docs: ../sessions/#messages 363 372 .. _permissions docs: ../authentication/#permissions 364 373 365 374 django.core.context_processors.debug … … 409 418 `HttpRequest object`_. Note that this processor is not enabled by default; 410 419 you'll have to activate it. 411 420 421 django.core.context_processors.messages 422 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 423 424 If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every 425 ``RequestContext`` will contain a variable ``messages``, which is a list of 426 messages (as strings) for the current session and the currently logged-in user. 427 See the `session messages docs`_ or the `authentication messages docs`_ for more 428 information on using messages. 429 430 Note that this processor is only useful if you are not using the (enabled by 431 default) ``auth`` processor, as it also provides the ``messages`` variable. 432 433 The messages are not retrieved and cleared (using ``get_and_delete_messages``) 434 until the ``messages`` variable is accessed in a template. 435 436 Here's an example of template code that displays messages made available by this 437 context processor:: 438 439 {% if messages %} 440 <ul> 441 {% for message in messages %} 442 <li>{{ message }}</li> 443 {% endfor %} 444 </ul> 445 {% endif %} 446 412 447 Writing your own context processors 413 448 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 414 449