Django显示进度条(超详细教学,有问有答)

意义

进度条在后台程序长时间处理时具有极大的意义

  1. 给用户及时的反馈,防止用户以为卡住而反复刷新重发请求
  2. 让用户良好地预估工作完成时间

需要的一些知识

  • 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)
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
要在 Django 中实现进度条动态展示,需要使用 Ajax 技术和 JavaScript/JQuery 实现。以下是一些步骤: 1. 在 Django 中定义视图函数来处理进度条相关的逻辑。 2. 在模板中使用 Ajax 技术来调用这个视图函数,并将进度条的值返回到前端。 3. 使用 JavaScript 或 JQuery 来动态更新进度条的值并展示出来。 以下是一个简单的示例代码: views.py ```python from django.http import JsonResponse from time import sleep def progress(request): for i in range(10): sleep(1) # 模拟一些长时间的处理 progress = (i+1)*10 data = { 'progress': progress } return JsonResponse(data) ``` urls.py ```python from django.urls import path from . import views urlpatterns = [ path('progress/', views.progress, name='progress'), ] ``` template.html ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>进度条展示</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> </head> <body> <h1>进度条展示</h1> <div id="progress-bar" style="width: 0%; height: 20px; background-color: green;"></div> <script> $(document).ready(function() { setInterval(function() { $.ajax({ url: "{% url 'progress' %}", success: function(data) { var progress = data.progress; $('#progress-bar').css('width', progress + '%'); } }); }, 1000); }); </script> </body> </html> ``` 在这个示例代码中,我们定义了一个 progress 视图函数来模拟一些长时间的处理,并将进度条的值作为 JSON 数据返回。 在模板中,我们使用 Ajax 技术来每秒钟调用一次这个视图函数,并将进度条的值传递到前端。然后,我们使用 JavaScript 或 JQuery 来动态更新进度条的值。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值