diff options
| author | Raffaele Salmaso <raffaele.salmaso@gmail.com> | 2017-01-10 00:03:10 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-01-09 18:03:10 -0500 |
| commit | ed8c0c941df0f321fb5751db572a9ec773d5118a (patch) | |
| tree | 7235cbbbef8f3b2ace26f46c2384ecae25fa0e6f | |
| parent | 7dc8d9238aed6267d6f21e05d0f02eb8ec2007ec (diff) | |
Fixed #27688 -- Made messages' add_message() request check use ducktyping.
| -rw-r--r-- | django/contrib/messages/api.py | 26 | ||||
| -rw-r--r-- | tests/messages_tests/test_api.py | 21 |
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) |
