'How to send message to user in a Django Thread?
I have a long time execution function that I run in a Thread to avoid blocking the user during the process. But I have a problem when I want to notify the user at the end of this function to tell him that it's done (and tell him if it was a success or an error). I tried to use django.contrib.messages but unsuccessful.
Here is my code simplified :
from threading import Thread
from django.contrib import messages
def my_view(request):
thread =Thread(target=run_creation, args=[request], daemon=True)
thread.start()
return render(request, 'main/home.html')
def run_creation(request):
print("sleep start")
time.sleep(20)
print("sleep end")
messages.add_message(request, messages.INFO, 'Hello word')
The problem is that I can't see the message in my template. Here is my template :
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
Thanks a lot for your help
Solution 1:[1]
I managed to solve it - 7 elegant steps.
Steps do so:
Install memcached as your cache backend.
docker run -p 11211:11211 --name local-memcache -d memcached memcached -m 64
Then go and
pip install django-async-messages django-pymemcacheAdd this to your
middlewareinsettings.pyfile:'async_messages.middleware.AsyncMiddleware'
Ensure it comes after 'django.contrib.messages.middleware.MessageMiddleware'
Then add this to your
settings.pyfile:CACHES = { 'default': { 'BACKEND': 'djpymemcache.backend.PyMemcacheCache', 'LOCATION': [ '127.0.0.1:11211', ], }, }
Where you want to use this async messaging, go
from async_messages import message_userSubstitute your classicalmessages.add_message(...formessage_user(request.user, "your message")where first agrument is a user objectgo to the
django-async-messagespackage because it is slightly obsolete and needs a small update. Locate themiddleware.pyfile in the package (likely invenv/Lib/site-packages/async_messages/middleware.py)Change it from this
from django.contrib import messages
from async_messages import get_messages
class AsyncMiddleware(object):
def process_response(self, request, response): """ Check for messages for this user and, if it exists, call the messages API with it """ if hasattr(request, "session") and hasattr(request, "user") and request.user.is_authenticated(): msgs = get_messages(request.user) if msgs: for msg, level in msgs: messages.add_message(request, level, msg) return response
to this:
from django.contrib import messages
from async_messages import get_messages
from django.utils.deprecation import MiddlewareMixin
class AsyncMiddleware(MiddlewareMixin):
def process_response(self, request, response):
"""
Check for messages for this user and, if it exists,
call the messages API with it
"""
if hasattr(request, "session") and hasattr(request, "user") and request.user.is_authenticated:
msgs = get_messages(request.user)
if msgs:
for msg, level in msgs:
messages.add_message(request, level, msg)
return response
That is it - you have asynchronous messaging!
Ps - because you just edited a package which would change when deploying - I exctracted the package and with above changes I included it directly in my project structure.
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 |
