Fixed #27688 -- Made messages' add_message() request check use ducktyping.

This commit is contained in:
Raffaele Salmaso 2017-01-10 00:03:10 +01:00 committed by Tim Graham
parent 7dc8d9238a
commit ed8c0c941d
2 changed files with 36 additions and 11 deletions

View File

@ -1,6 +1,5 @@
from django.contrib.messages import constants
from django.contrib.messages.storage import default_storage
from django.http import HttpRequest
__all__ = (
'add_message', 'get_messages',
@ -18,16 +17,21 @@ def add_message(request, level, message, extra_tags='', fail_silently=False):
"""
Attempts to add a message to the request using the 'messages' app.
"""
if not isinstance(request, HttpRequest):
raise TypeError("add_message() argument must be an HttpRequest object, "
"not '%s'." % request.__class__.__name__)
if hasattr(request, '_messages'):
return request._messages.add(level, message, extra_tags)
if not fail_silently:
raise MessageFailure(
'You cannot add messages without installing '
'django.contrib.messages.middleware.MessageMiddleware'
)
try:
messages = request._messages
except AttributeError:
if not hasattr(request, 'META'):
raise TypeError(
"add_message() argument must be an HttpRequest object, not "
"'%s'." % request.__class__.__name__
)
if not fail_silently:
raise MessageFailure(
'You cannot add messages without installing '
'django.contrib.messages.middleware.MessageMiddleware'
)
else:
return messages.add(level, message, extra_tags)
def get_messages(request):

View File

@ -42,3 +42,24 @@ class ApiTests(SimpleTestCase):
def test_middleware_missing_silently(self):
messages.add_message(self.request, messages.DEBUG, 'some message', fail_silently=True)
self.assertEqual(self.storage.store, [])
class CustomRequest(object):
def __init__(self, request):
self._request = request
def __getattribute__(self, attr):
try:
return super(CustomRequest, self).__getattribute__(attr)
except AttributeError:
return getattr(self._request, attr)
class CustomRequestApiTests(ApiTests):
"""
add_message() should use ducktyping to allow request wrappers such as the
one in Django REST framework.
"""
def setUp(self):
super(CustomRequestApiTests, self).setUp()
self.request = CustomRequest(self.request)