如何在django视图中显示请等待加载消息?
我有一个Django视图,需要很长时间才能对大型数据集执行计算。
当进程加载时,我想向用户显示反馈消息,例如:旋转加载动画gif或类似内容。
答案 0 :(得分:3)
在尝试了布兰登和穆拉特提出的两种不同方法之后,布兰登的建议被证明是最成功的。
创建一个包含来自http://djangosnippets.org/snippets/679/的javascript的包装器模板。 javascript已被修改:(i)在没有表单的情况下工作(ii)在返回'done'标志时隐藏进度条/显示结果(iii),JSON更新url指向下面描述的视图
将慢速加载功能移动到线程。该线程将传递一个缓存键,并负责更新缓存的进度状态,然后更新其结果。该线程将原始模板呈现为字符串并将其保存到缓存中。
创建一个基于upload_progress的视图,从http://djangosnippets.org/snippets/678/修改为(i)代替渲染原始包装模板,如果progress_id =''(ii)生成cache_key,检查缓存是否已存在,如果不存在启动一个新线程(iii)监视线程的进度,完成后将结果传递给包装器模板
包装器模板通过document.getElementById('main').innerHTML=data.result
(*查看步骤4是否可以通过重定向更好地实现,因为呈现的模板包含当前未由document.getElementById('main').innerHTML=data.result
运行的javascript)
答案 1 :(得分:1)
这是一个老人,但可能会让你朝着正确的方向前进:http://djangosnippets.org/snippets/679/
答案 2 :(得分:1)
更简单的方法是使用您的gif等生成等待页面,然后使用javascript
window.location.href = 'insert results view here';
切换到开始冗长计算的结果视图。在计算完成之前,页面不会更改。完成后,将呈现结果页面。
答案 3 :(得分:1)
您可以做的另一件事是添加一个JavaScript函数,该函数在实际调用Django View之前显示加载图像。
function showLoaderOnClick(url) {
showLoader();
window.location=url;
}
function showLoader(){
$('body').append('<div style="" id="loadingDiv"><div class="loader">Loading...</div></div>');
}
然后在您的模板中可以执行以下操作:
<a href='#' onclick="showLoaderOnClick('{% url 'my_namespace:my_view' %}')">This will take some time...</a>
这是一个快速的默认loadingDiv:https://stackoverflow.com/a/41730965/13476073 请注意,这需要jQuery。
答案 4 :(得分:0)
迭代HttpResponse
https://stackoverflow.com/a/1371061/198062
编辑:
我找到了一个用django发送大文件的例子:http://djangosnippets.org/snippets/365/然后我看看FileWrapper类(django.core.servers.basehttp):
class FileWrapper(object):
"""Wrapper to convert file-like objects to iterables"""
def __init__(self, filelike, blksize=8192):
self.filelike = filelike
self.blksize = blksize
if hasattr(filelike,'close'):
self.close = filelike.close
def __getitem__(self,key):
data = self.filelike.read(self.blksize)
if data:
return data
raise IndexError
def __iter__(self):
return self
def next(self):
data = self.filelike.read(self.blksize)
if data:
return data
raise StopIteration
我认为我们可以制作一个像这样的可迭代类
class FlushContent(object):
def __init__(self):
# some initialization code
def __getitem__(self,key):
# send a part of html
def __iter__(self):
return self
def next(self):
# do some work
# return some html code
if finished:
raise StopIteration
然后在views.py
中def long_work(request):
flushcontent = FlushContent()
return HttpResponse(flushcontent)
编辑:
示例代码,仍无效:
class FlushContent(object):
def __init__(self):
self.stop_index=2
self.index=0
def __getitem__(self,key):
pass
def __iter__(self):
return self
def next(self):
if self.index==0:
html="loading"
elif self.index==1:
import time
time.sleep(5)
html="finished loading"
self.index+=1
if self.index>self.stop_index:
raise StopIteration
return html
答案 5 :(得分:0)
这是关于如何获取长期加载Django视图的加载消息的另一种解释
进行大量处理的视图(例如,包含多个对象的复杂查询,访问第三方API)可能需要花费一些时间才能加载页面并将其显示在浏览器中。发生的事情是所有这些处理都是在服务器上完成的,而Django无法在完成页面之前为其提供服务。
在处理过程中显示显示加载消息(例如微调gif)的唯一方法是将当前视图分为两个视图:
第一个视图在不进行任何处理和加载消息的情况下呈现页面
页面包括对第二个视图的AJAX调用,该视图执行实际处理。使用AJAX / JavaScript完成处理后,处理结果将显示在页面上
答案 6 :(得分:0)
我选择的一种解决方法是使用beforunload
和unload
事件来显示加载图像。可以与window.load
一起使用,也可以不使用。就我而言,视图需要花费大量时间而不是页面加载,因此我没有使用window.load
。
不利之处在于,即使请求尚未到达服务器或花费大量时间,也会向用户发出错误消息,表明页面正在加载。并且,由于某种原因,请求消失了,用户将继续认为该页面正在加载中。但是我现在正在忍受这个。
P.S。我无法发表评论,因此将其发布为答案。