Fixed #12575 - created a better interface for getting/setting the effective level of contrib.messages

Thanks Chris Beaven.



git-svn-id: http://code.djangoproject.com/svn/django/trunk@12207 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Luke Plant 2010-01-12 02:41:57 +00:00
parent 2f9853b2dc
commit c56beed240
3 changed files with 78 additions and 15 deletions

View File

@ -1,4 +1,5 @@
from django.contrib.messages import constants from django.contrib.messages import constants
from django.contrib.messages.storage import default_storage
from django.utils.functional import lazy, memoize from django.utils.functional import lazy, memoize
__all__ = ( __all__ = (
@ -44,6 +45,34 @@ def get_messages(request):
return lazy(memoize(get_user().get_and_delete_messages, {}, 0), list)() return lazy(memoize(get_user().get_and_delete_messages, {}, 0), list)()
def get_level(request):
"""
Returns the minimum level of messages to be recorded.
The default level is the ``MESSAGE_LEVEL`` setting. If this is not found,
the ``INFO`` level is used.
"""
if hasattr(request, '_messages'):
storage = request._messages
else:
storage = default_storage(request)
return storage.level
def set_level(request, level):
"""
Sets the minimum level of messages to be recorded, returning ``True`` if
the level was recorded successfully.
If set to ``None``, the default level will be used (see the ``get_level``
method).
"""
if not hasattr(request, '_messages'):
return False
request._messages.level = level
return True
def debug(request, message, extra_tags='', fail_silently=False): def debug(request, message, extra_tags='', fail_silently=False):
""" """
Adds a message with the ``DEBUG`` level. Adds a message with the ``DEBUG`` level.

View File

@ -3,11 +3,11 @@ from django.test import TestCase
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext_lazy from django.utils.translation import ugettext_lazy
from django.contrib.messages import constants, utils from django.contrib.messages import constants, utils
from django.contrib.messages.api import MessageFailure, get_level, set_level
from django.contrib.messages.storage import default_storage, base from django.contrib.messages.storage import default_storage, base
from django.contrib.messages.storage.base import Message from django.contrib.messages.storage.base import Message
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.messages.api import MessageFailure
def add_level_messages(storage): def add_level_messages(storage):
@ -41,16 +41,19 @@ class BaseTest(TestCase):
if hasattr(settings, setting): if hasattr(settings, setting):
self._remembered_settings[setting] = getattr(settings, setting) self._remembered_settings[setting] = getattr(settings, setting)
delattr(settings._wrapped, setting) delattr(settings._wrapped, setting)
# backup these manually because we do not want them deleted # Backup these manually because we do not want them deleted.
self._middleware_classes = settings.MIDDLEWARE_CLASSES self._middleware_classes = settings.MIDDLEWARE_CLASSES
self._template_context_processors = \ self._template_context_processors = \
settings.TEMPLATE_CONTEXT_PROCESSORS settings.TEMPLATE_CONTEXT_PROCESSORS
self._installed_apps = settings.INSTALLED_APPS self._installed_apps = settings.INSTALLED_APPS
self._message_storage = settings.MESSAGE_STORAGE
settings.MESSAGE_STORAGE = '%s.%s' % (self.storage_class.__module__,
self.storage_class.__name__)
def tearDown(self): def tearDown(self):
for setting in self.restore_settings: for setting in self.restore_settings:
self.restore_setting(setting) self.restore_setting(setting)
# restore these manually (see above) # Restore these manually (see above).
settings.MIDDLEWARE_CLASSES = self._middleware_classes settings.MIDDLEWARE_CLASSES = self._middleware_classes
settings.TEMPLATE_CONTEXT_PROCESSORS = \ settings.TEMPLATE_CONTEXT_PROCESSORS = \
self._template_context_processors self._template_context_processors
@ -319,25 +322,48 @@ class BaseTest(TestCase):
self.assert_(storage.added_new) self.assert_(storage.added_new)
def test_default_level(self): def test_default_level(self):
# get_level works even with no storage on the request.
request = self.get_request()
self.assertEqual(get_level(request), constants.INFO)
# get_level returns the default level if it hasn't been set.
storage = self.get_storage() storage = self.get_storage()
request._messages = storage
self.assertEqual(get_level(request), constants.INFO)
# Only messages of sufficient level get recorded.
add_level_messages(storage) add_level_messages(storage)
self.assertEqual(len(storage), 5) self.assertEqual(len(storage), 5)
def test_low_level(self): def test_low_level(self):
storage = self.get_storage() request = self.get_request()
storage.level = 5 storage = self.storage_class(request)
request._messages = storage
self.assert_(set_level(request, 5))
self.assertEqual(get_level(request), 5)
add_level_messages(storage) add_level_messages(storage)
self.assertEqual(len(storage), 6) self.assertEqual(len(storage), 6)
def test_high_level(self): def test_high_level(self):
storage = self.get_storage() request = self.get_request()
storage.level = 30 storage = self.storage_class(request)
request._messages = storage
self.assert_(set_level(request, 30))
self.assertEqual(get_level(request), 30)
add_level_messages(storage) add_level_messages(storage)
self.assertEqual(len(storage), 2) self.assertEqual(len(storage), 2)
def test_settings_level(self): def test_settings_level(self):
request = self.get_request()
storage = self.storage_class(request)
settings.MESSAGE_LEVEL = 29 settings.MESSAGE_LEVEL = 29
storage = self.get_storage() self.assertEqual(get_level(request), 29)
add_level_messages(storage) add_level_messages(storage)
self.assertEqual(len(storage), 3) self.assertEqual(len(storage), 3)

View File

@ -137,8 +137,11 @@ Constant Purpose
``ERROR`` An action was **not** successful or some other failure occurred ``ERROR`` An action was **not** successful or some other failure occurred
=========== ======== =========== ========
The `MESSAGE_LEVEL`_ setting can be used to change the minimum recorded The `MESSAGE_LEVEL`_ setting can be used to change the minimum recorded level
level. Attempts to add messages of a level less than this will be ignored. (or it can be `changed per request`_). Attempts to add messages of a level less
than this will be ignored.
.. _`changed per request`: `Changing the minimum recorded level per-request`_
Message tags Message tags
------------ ------------
@ -245,22 +248,27 @@ provide a mapping via the `MESSAGE_TAGS`_ setting.
Changing the minimum recorded level per-request Changing the minimum recorded level per-request
----------------------------------------------- -----------------------------------------------
The minimum recorded level can be set per request by changing the ``level`` The minimum recorded level can be set per request via the ``set_level``
attribute of the messages storage instance:: method::
from django.contrib import messages from django.contrib import messages
# Change the messages level to ensure the debug message is added. # Change the messages level to ensure the debug message is added.
messages.get_messages(request).level = messages.DEBUG messages.set_level(request, messages.DEBUG)
messages.debug(request, 'Test message...') messages.debug(request, 'Test message...')
# In another request, record only messages with a level of WARNING and higher # In another request, record only messages with a level of WARNING and higher
messages.get_messages(request).level = messages.WARNING messages.set_level(request, messages.WARNING)
messages.success(request, 'Your profile was updated.') # ignored messages.success(request, 'Your profile was updated.') # ignored
messages.warning(request, 'Your account is about to expire.') # recorded messages.warning(request, 'Your account is about to expire.') # recorded
# Set the messages level back to default. # Set the messages level back to default.
messages.get_messages(request).level = None messages.set_level(request, None)
Similarly, the current effective level can be retrieved with ``get_level``::
from django.contrib import messages
current_level = messages.get_level(request)
For more information on how the minimum recorded level functions, see For more information on how the minimum recorded level functions, see
`Message levels`_ above. `Message levels`_ above.