无需请求即可在 Django 中显示消息

问题描述

我有一个使用线程的视图,例如

from .utils import my_heavy_function
def my_view(request):

    if request.method == "POST":
       form = my_model_form()

        if form.is_valid():
            
            #create thread
            thr = threading.Thread(target=my_heavy_function,args=(form,))
            thr.start()
            messages.success(request,"Processing ...")

            return redirect("my_template")
    else:
        form = my_model_form()
    return render(request,"my_app/my_template.html")

它就像一个魅力;它在后台处理 my_heavy_function,同时使用户能够继续使用网页。我只需要一种在 my_heavy_function 完成后显示消息的方法

有没有办法让 Django 显示一条消息,即使没有调用新请求,而是基于其他条件?例如在文件加载完成后的页面上。

(我故意不使用 Django-Q、Celery 或后台任务来处理这个线程,因为我发现它太过分了)

解决方法

你想做什么不是很清楚。如果您想在不执行 HTTP 请求的情况下通知用户,那么您在 Web 技术中唯一的选择就是设置一个 WebSocket,以便您可以从服务器推送内容。

如果用户下次打开页面时可以收到消息,那么您可以在完成繁重的任务后将某些内容放入数据库中。对于每个请求,您检查数据库中是否有内容,您将执行 messages.add_message 并从数据库中删除该行。

,

要使消息正常工作,您需要编辑 settings.py

settings.py

INSTALLED_APPS = [
...
'django.contrib.messages',...
]


django.contrib.messages

是的,您可以通过 Django 中的视图在模板中显示消息。

将此添加到您的模板中: index.html

{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

现在每当有新消息时,它都会显示在您的模板中。 在您的代码中,您可以使用 try,除了像这样的块

view.py

from .utils import my_heavy_function
def my_view(request):

    if request.method == "POST":
       form = my_model_form()

        if form.is_valid():
            thr = threading.Thread(target=my_heavy_function,args=(form,))
            thr.start()
            # Need to save form ??? form.save() ??????
            messages.add_message(request,Messages.INFO,"form saved")
        
        try:
            # run function here.
            messages.add_message(request,message.INFO,"Sucess! ")
            return redirect("my_template")
        except Exception as e:
            # For testing print(e)
            messages.add_message(request,"Error! ")
            return redirect('my_template")
            
    else:
        form = my_model_form()
    return render(request,"my_app/my_template.html")

更多信息: https://docs.djangoproject.com/en/3.1/ref/contrib/messages/