summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaffaele Salmaso <raffaele.salmaso@gmail.com>2017-01-10 00:03:10 +0100
committerTim Graham <timograham@gmail.com>2017-01-09 18:03:10 -0500
commited8c0c941df0f321fb5751db572a9ec773d5118a (patch)
tree7235cbbbef8f3b2ace26f46c2384ecae25fa0e6f
parent7dc8d9238aed6267d6f21e05d0f02eb8ec2007ec (diff)
Fixed #27688 -- Made messages' add_message() request check use ducktyping.
-rw-r--r--django/contrib/messages/api.py26
-rw-r--r--tests/messages_tests/test_api.py21
2 files changed, 36 insertions, 11 deletions
diff --git a/django/contrib/messages/api.py b/django/contrib/messages/api.py
index ceb6057f8d..f77cf26de5 100644
--- a/django/contrib/messages/api.py
+++ b/django/contrib/messages/api.py
@@ -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):
diff --git a/tests/messages_tests/test_api.py b/tests/messages_tests/test_api.py
index 0cb17c1656..8baff57c70 100644
--- a/tests/messages_tests/test_api.py
+++ b/tests/messages_tests/test_api.py
@@ -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)