服务器正在处理视图时,如何在 Django 中显示加载动画?

How can I show a loading animation in Django while the server is processing a view?

所以我目前正在开发一个 Django 项目,该项目的视图需要花费大量时间才能加载,而且在页面加载之前让用户一直想知道网站出了什么问题,这对用户来说可能相当不友好。

我的网站的工作方式使得用户会有 url 例如:

http://www.example.com/Name/JohnRichards

已保存到他们的书签。访问上面的 URL 服务器应该显示加载屏幕的加载消息(可能带有 GIF 和 AJAX 或 JS),直到服务器完成加载数据然后显示它。

注意:以防万一,当用户转到上面提到的 link 时,他们不会被重定向到那里,相反,这将是他们的入口点,因为这是他们保存在书签中的 url

我认为可行的是 return 在有人访问页面时立即加载某种加载模板,然后在数据处理完成后,我会 return最后的回应。但是我不能在一个函数中有两个 return。

以下是我的urls.py文件:

from django.contrib import admin
from django.urls import path
from myapp import views

urlpatterns = [
    path('', views.index, name='index'),
    path('Name/'+'<str:Name>', views.NameInLink, name='NameInLink'),
]

下面是我的views.py文件

from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from .forms import NameForm
from . import DataProcessor
import time

def NameInLink(request, Name):
    UserData = DataProcessor.process(Name)
    return render(request, "UserData.html", {"UserData": UserData})

如何在用户访问 URL 和数据处理完成之间添加一个加载屏幕?

我建议将加载模板(GIF 或其他)放入页面的默认模板中。然后,当 Ajax 调用成功返回时,使用 javascript.

隐藏或删除正在加载的 GIF

我认为没有必要使用 Ajax 发送加载模板,如果我理解正确的话。

编辑

您不能从一个视图发送两个连续的响应。在您看来,在处理用户数据之前无法发送响应。

所以我认为你的流程应该是这样的:

  1. 打开没有用户数据的加载模板
def NameInLink(request, Name):
    return render(request, "UserData.html")
  1. 加载页面后,应向第二个视图发送 AJAX 请求(接收 html 数据),例如:
    def process_data(request, name):
        userData = DataProcessor.process(name)
        context = {'data': userData}
        result = render_to_string("some_results_template", context)
        data = {'data': result}
        return JsonReponse(data)
  1. 在 AJAX 调用成功 return 后删除 GIF 并使用 javaScript
  2. 添加 returned 数据

这是一个非常精简的脚本模板示例,只是为了让答案更清楚

<head>
    <!-- Don't forget to load jQuery -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head> 

<body>
<h1>Default Page</h1> 

<!-- The loading image -->
<div id="loading">
    <p>Loading</p>
</div>

<!-- Container for result -->
<div id="success">

</div>

<script>

    // Function for adding User data and removing loading animation
    var replace_data = function(data){
        $('#success').append(data.data);
        $('#loading').remove();
    }

    // AJAX call when page has loaded
    $(document).ready(function(){
        $.ajax({
            url: '/test2/',
            data: {
                'name': 'FOO'
            },
            data_type: 'html',
            success: function(data){
                replace_data(data);
            }
        });
    });

</script>
</body>