意义
进度条在后台程序长时间处理时具有极大的意义
- 给用户及时的反馈,防止用户以为卡住而反复刷新重发请求
- 让用户良好地预估工作完成时间
需要的一些知识
- Django结构知识
- Html,jQuery,JavaScript,BootStrap的一些简单的知识
当然以上都可以在菜鸟教程很快获取
操作
页面/模板
cut/template/cut/project.html
- 设置按键,并在按键处理函数中
GET show_process
的请求(注意修改成自己的路由 - 用 当前处理的秒数 除以 百分比,算一个总时间,然后减去现在的时间,得到剩余时间得了
- 把秒数处理成等待的时间
<!DOCTYPE html>
<html>
<head>
<title>工程详情页</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col-8">
<h2 class="mt-2">工程: {{ project.name }}</h2>
<hr class="mt-0 mb-4">
{% block content %}
<!-- ... -->
<h2> 处理视频: </h2>
<div class="container">
<!--1. 按钮-->
<!-- <button class="btn btn-default" type="button">点击进行处理_Test</button> -->
<!-- 使用的Project_Detail类里面的post,所以无单独的url -->
<form enctype="multipart/form-data" action="" method="post">
{% csrf_token %}
<input class="btn btn-default" type="submit" value="点击进行处理"/>
</form>
<!--2. 进度条-->
<div class="progress-div">
<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 0em; width: 0%;">
0%
</div>
</div>
</div>
</br>
<div class="progress-text progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 0em; width: 0%;">
</div>
</div>
<br>
<h2 class="mt-2">返回</h2>
<hr class="mt-0 mb-4">
<h3><a href="{% url 'cut:index' %}"> 返回主页</a></h3>
{% endblock %}
</div>
</div>
</div>
</body>
<script>
function secondToDate(result) {
var h = Math.floor(result / 3600);
var m = Math.floor((result / 60 % 60));
var s = Math.floor((result % 60));
if (h) {
return result = h + "小时" + m + "分钟" + s + "秒";
}
else if (m) {
return result = m + "分钟" + s + "秒";
}
else {
return result = s + "秒";
}
}
$(function () {
$('.btn').on('click', function () {
// 设置按一次后禁用,发现只有进度条生效了,但是处理函数没有生效--[pass]先
// $('.btn').attr("disabled", "true");
// $('.btn').removeAttr("disabled");
console.log("come in ")
var cur_second = 0
var left_time = 0
var sitv = setInterval(function () {
// 请求url,一定要加上应用头, cut
var prog_url = '/cut/show_progress'
$.getJSON(prog_url, function (process_percent) {
cur_second += 1
if (process_percent) {
// 用 当前处理的秒数 除以 百分比,算一个总时间,然后减去现在的时间,得到剩余时间得了
left_time = cur_second * 100 / parseInt(process_percent) - cur_second;
$('.progress-div').css('visibility', 'visible');
$('.progress-bar').css('width', process_percent + '%');
$('.progress-bar').text(process_percent + '%');
var rest_str = '';
if (left_time > 3600) {
// 超1小时
rest_str = ' 去楼下转转放松一下吧,小机在全速处理中...'
}
else if (left_time > 300) {
// 5分钟 -- 1小时
rest_str = ' 稍微干点别的事情吧,小机在努力...';
}
else if (left_time > 40) {
// 40s -- 5分钟
rest_str = ' 喝杯茶上个厕所休息一下吧,小机过会就好了哦...';
}
else {
// 40s内
rest_str = ' 马上就要转码视频了,是不是有点期待呢...'
}
$('.progress-text').text('大约还剩下' + secondToDate(left_time) + rest_str);
}
$('.progress-text').css('width', '100%');
// 改变进度条进度,注意这里是内层的div, res是后台返回的进度
if (process_percent == "100") {
console.log("come in 100")
// 清除自己是真的秀,这jQuery和JavaScript有点牛逼
clearInterval(sitv);
$('.progress-text').text('结果视频正在转码保存中,即将跳转结果页面,请稍后...');
$('.progress-bar').css('width', '100%');
$('.progress-bar').text('100%');
}
});
// 每1秒查询一次后台进度
}, 1000);
})
})
</script>
</html>
路由
cut/url.py
re_path(r'show_progress/$', views.show_progress),
from django.urls import path, re_path
from . import views
app_name = 'cut'
urlpatterns = [
# 第一个参数是真实的链接路径
# 第二个参数是选择处理此路径的视图函数
# name 用于 html文件中快速link
# 首页
path('', views.IndexView.as_view(), name='index'),
# 工程详情
path('<int:pk>/', views.DetailView.as_view(), name='project'),
# 创建工程系列
# ...
# 进度条
re_path(r'show_progress/$', views.show_progress),
]
视图函数及处理函数
cut/view.py
通过类函数,获取处理进度 (把处理进度设置为类变量)
class DetailView(generic.DetailView):
MS_TO_SECOND = 1000
TIME_COUNT = 60
model = Project
template_name = 'cut/project.html'
project_context = None
video_stream = None
frameCount = 0
processing = 0
@classmethod
def get_frame_count(cls):
return cls.frameCount
@classmethod
def get_processing(cls):
return cls.processing
def show_progress(request):
'''
前端JS需要访问此程序来更新数据
通过类函数,获取处理进度 (把处理进度设置为类变量)
'''
total = DetailView.get_frame_count()
if total:
process_percent = round(DetailView.get_processing() / total * 100)
else:
process_percent = 0
print('current process percent is - {}%.'.format(process_percent))
return JsonResponse(process_percent, safe=False)