jquery - 在 Django 中使用 AJAX 获取 celery 进度
问题描述
我是 Web 开发的新手。我想上传一个文件并在 Celery 任务中处理它,并使用 AJAX 显示进度百分比。我使用了一些这样的示例,这是我的代码:
视图.py:
def importnewdata(request):
if request.method == 'POST':
form = RawFileAddressForm(request.POST, request.FILES)
if form.is_valid():
file = request.FILES['file']
file_name = default_storage.save("sample.txt", file)
task = process_file.delay(file_name)
return HttpResponse(json.dumps({'task_id': task.id}), content_type='application/json')
else:
return HttpResponse("Error1!")
else:
form = RawFileAddressForm()
return render(request, 'modelmanager/importnewdata.html', {'form': form})
def get_task_info(request):
task_id = request.GET.get('task_id', None)
if task_id is not None:
task = AsyncResult(task_id)
data = {
'state': task.state,
'result': task.result,
}
return HttpResponse(json.dumps(data), content_type='application/json')
else:
return HttpResponse('No job id given.')
表格.py:
class RawFileAddressForm(forms.Form):
file = forms.FileField()
导入新数据.html:
<!DOCTYPE html>
<html>
<head>
<title>import new raw data to db</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body style="text-align: center;">
<h1>select your file to process it!</h1>
<progress id="progress-bar" value="0" max="100" style="display:none; margin-bottom: 1em;"></progress>
<form id="process-raw-data" action="/modelmanager/importnewdata/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit"/>
</form>
<script type="text/javascript">
var frm = $('#process-raw-data');
var pgrbar = $('#progress-bar');
frm.submit(function () {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
if (data.task_id != null) {
get_task_info(data.task_id);
}
},
error: function (data) {
frm.html("error!");
}
});
return false;
});
function get_task_info(task_id) {
$.ajax({
type: 'get',
url: '/modelmanager/get-task-info/',
data: {'task_id': task_id},
success: function (data) {
frm.html('');
if (data.state == 'PENDING') {
frm.html('Please wait...');
}
else if (data.state == 'PROGRESS') {
pgrbar.css('display', 'inline');
pgrbar.val(data.result.percent);
frm.html('lines processed ' + data.result.current + ' out of ' + data.result.total);
}
else if(data.state == 'SUCCESS'){
pgrbar.css('display', 'none');
frm.html('Successfully Completed!');
}
if (data.state != 'SUCCESS') {
setTimeout(function () {
get_task_info(task_id)
}, 500);
}
},
error: function (data) {
frm.html("error!");
}
});
}
</script>
</body>
</html>
问题是单击提交按钮后没有任何反应。我有:
“POST /modelmanager/importnewdata/HTTP/1.1”200 10
在 Wireshark 我看到
错误1!
作为回应。这意味着表单无效,但是当我从 html 文件中删除 JS 部分时,它会返回一个带有成功创建的 celery 任务 ID 的 json 对象。这意味着表单是有效的。任何帮助。谢谢。
解决方案
谢谢大家。你帮了我很多!:)
最后,这是我的解决方案:
视图.py:
def importnewdata(request):
cntx = {}
if request.method == 'POST':
form = RawFileAddressForm(request.POST, request.FILES)
if form.is_valid():
file = request.FILES['file']
file_name = default_storage.save("sample.txt", file)
task = process_file.delay(file_name)
cntx['task_id'] = task.id
return render(request, 'modelmanager/importnewdata.html', cntx)
else:
return render(request, 'modelmanager/importnewdata.html', {'form':form})
else:
form = RawFileAddressForm()
return render(request, 'modelmanager/importnewdata.html', {'form': form})
def get_task_info(request):
task_id = request.GET.get('task_id', None)
if task_id is not None:
task = AsyncResult(task_id)
data = {
'state': task.state,
'result': task.result,
}
return HttpResponse(json.dumps(data), content_type='application/json')
else:
return HttpResponse('No job id given.')
导入新数据.html:
<!DOCTYPE html>
<html>
<head>
<title>import new raw data to db</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body style="text-align: center;">
<h1>select your file to process it!</h1>
<progress id="progress-bar" value="0" max="100" style="display:none; margin-bottom: 1em;"></progress>
<form id="process-raw-data" action="/modelmanager/importnewdata/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
{% if task_id %}
<script type="text/javascript">
var taskid = "{{task_id}}";
var frm = $('#process-raw-data');
var pgrbar = $('#progress-bar');
get_task_info(taskid);
function get_task_info(tid) {
$.ajax({
type: 'get',
url: '/modelmanager/get-task-info/',
data: {'task_id': tid},
success: function (data) {
frm.html('');
if (data.state == 'PENDING') {
frm.html('Please wait...');
}
else if (data.state == 'PROGRESS') {
pgrbar.css('display', 'inline');
pgrbar.val(data.result.percent);
frm.html('lines processed ' + data.result.current + ' out of ' + data.result.total);
}
else if(data.state == 'SUCCESS'){
pgrbar.css('display', 'none');
frm.html('Successfully Completed!');
}
if (data.state != 'SUCCESS') {
setTimeout(function () {
get_task_info(tid)
}, 500);
}
},
error: function (data) {
frm.html("error!");
}
});
}
</script>
{% endif %}
</body>
</html>
推荐阅读
- sql - MSSQL - 如何将 cpu_time(ms) 使用率转换为百分比?
- angular - 实现 ngRx 时出错“类型‘操作’上不存在属性‘管道’
’。” - python-3.x - pyhf中小信号模型的拟合收敛失败
- python - 多通道卷积神经网络 - 负维度尺寸误差
- javascript - 将气泡中的行添加到数据图上的弹出模板
- kubernetes - 有没有办法根据我的集群当前资源来限制 cpu 的使用?
- google-chrome - 无法连接到 Twilio:信号连接错误
- sql-server - 子查询返回超过 1 个值。当子查询跟随 =、!=、<、<=、>、>= 时,这是不允许的
- jquery - jQuery DateTimePicker 插件 - 相应地更改标题文本
- javascript - 综合创建一个“拖动”元素