'You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware

I am new to Django. I am trying to run an app and I need to add a new user to admin. The server is running. When I enter the info fir the new user and hit "save" I get the error below. I am using django-trunk.

MessageFailure at /admin/auth/user/add/
You cannot add messages without installing
django.contrib.messages.middleware.MessageMiddleware

Request Method: POST
Request URL:    http://localhost:8000/admin/auth/user/add/
Django Version: 1.6.dev20130403090717
Exception Type: MessageFailure
Exception Value:    You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware

Any ideas of what might be happening?



Solution 1:[1]

For me the problem was specific to unit testing. It turns out that some middleware won't work in some kinds of unit tests, more info here:

https://code.djangoproject.com/ticket/17971

and here:

Why don't my Django unittests know that MessageMiddleware is installed?

My solution was to just mock out the messages framework for those tests, there may be better solutions (the django test client?)

Solution 2:[2]

Check if you have django.contrib.messages in INSTALLED_APPS and django.contrib.messages.middleware.MessageMiddleware in MIDDLEWARE_CLASSES.

Solution 3:[3]

If you are running normal django code, you should add django.contrib.messages.middleware.MessageMiddleware to your middlewares as others have suggested

If you are running a test case and using request factory then as @hwjp answered above, it's a bug (that won't be fixed). The request factory doesn't call the middlewares and developers don't intend to change this behaviour.

There is however a simple solution.

in your test settings file (i.e settings/test.py) add the following line

MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'

in your test code you can write code like this

request = RequestFactory().get("/")
# Add support  django messaging framework
request._messages = messages.storage.default_storage(request)

and that's it. Passing this request object to any code that uses django messages will work without a problem.

Solution 4:[4]

Check if it is

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

instead of

MIDDLEWARE = (
   'django.middleware.common.CommonMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   'django.contrib.messages.middleware.MessageMiddleware',
)

Tuple name should be MIDDLEWARE_CLASSES

MIDDLEWARE_CLASSES depreciated https://docs.djangoproject.com/en/2.1/releases/1.10/#id3

Solution 5:[5]

2018 update In django 2.0+ name in settings was changed. Right now use MIDDLEWARE instead of MIDDLEWARE_CLASSES name of list in settings!

Solution 6:[6]

Probably you put a wrong WSGI_request when usually called request as a parameter to add_message() method

Solution 7:[7]

I met the same error. You have to notice the order of middleware in MIDDLEWARE_CLASSES. Insert the corresponding middleware in the final.Like this,

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

Note the order arrangement.

Solution 8:[8]

If the request is needed in tests, it can be mocked as suggested by @Ramast. I found the solution mentioned in the bug ticket (closed, won't fix) to be helpful.

from django.contrib.messages.storage.fallback import FallbackStorage
from django.test import RequestFactory


def dummy_request():
    """Dummy request for testing purposes with message support."""
    request = RequestFactory().get('/')
    # Add support django messaging framework
    setattr(request, 'session', 'session')
    setattr(request, '_messages', FallbackStorage(request))
    return request

Solution 9:[9]

If your issue is simulating these middlewares during unit testing, you can spoof this by writing a couple of little helpers:

def add_session_to_request(request: HttpRequest) -> HttpRequest:
    """Adds session support to a RequestFactory generated request."""
    middleware = SessionMiddleware(get_response=lambda request: None)
    middleware.process_request(request)
    request.session.save()
    return request


def add_messages_to_request(request: HttpRequest) -> HttpRequest:
    """Adds message/alert support to a RequestFactory generated request."""
    request._messages = FallbackStorage(request)
    return request

You can then call these in your test function at the point your request needs to have the middleware bound and just pass in the request you're using, which should keep your tests happy. :)

# To suppress the errors raised when triggering .messages through APIRequestFactory(),
            # we need to bind both a session and messages storage on the fly
            add_session_to_request(replacement_request)
            add_messages_to_request(replacement_request)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hwjp
Solution 2
Solution 3
Solution 4
Solution 5 Marek Szmalc
Solution 6 Aditya Kresna Permana
Solution 7 kylieCatt
Solution 8
Solution 9 thms