Django 4执行脚本任务时,如何向页面实时输出状态信息?
实现实时任务进度显示的简便方案
1. 改造任务逻辑,支持进度追踪
先修改models.py里的main方法,让它能接收一个进度存储容器,执行过程中实时更新状态:
# models.py def main(progress_tracker): total_steps = 10 # 根据实际任务步骤数调整 progress_tracker['current'] = 0 progress_tracker['status'] = '任务开始' # 第一步处理 # ... 你的业务逻辑代码 progress_tracker['current'] = 1 progress_tracker['status'] = '完成文件解析' # 第二步处理 # ... 你的业务逻辑代码 progress_tracker['current'] = 3 progress_tracker['status'] = '完成数据清洗' # ... 后续任务步骤 progress_tracker['current'] = total_steps progress_tracker['status'] = '任务全部完成'
2. 改造视图,异步执行任务并存储进度
在views.py中用线程后台跑耗时任务,把进度存在用户session里(小流量场景足够简便):
# views.py import threading from django.shortcuts import render from django.http import JsonResponse from .models import MyModel def upload(request): if request.method == 'POST': # 处理文件上传逻辑 # ... 你的文件接收、校验代码 # 初始化进度字典,存入session request.session['task_progress'] = {'current': 0, 'status': '准备启动任务', 'completed': False} request.session.save() # 强制保存session,避免线程读取不到 # 后台线程执行任务 def run_background_task(): MyModel.main(request.session['task_progress']) request.session['task_progress']['completed'] = True request.session.save() threading.Thread(target=run_background_task).start() # 跳转到进度展示页面 return render(request, 'frontend/progress.html') # GET请求返回上传表单 form = ... # 你的表单实例 return render(request, 'frontend/upload.html', {'form': form}) # 新增获取进度的接口视图 def get_progress(request): progress = request.session.get('task_progress', {'current': 0, 'status': '无正在执行的任务'}) return JsonResponse(progress)
3. 配置URL路由
在项目urls.py中添加进度接口的路由:
# urls.py from django.urls import path from . import views urlpatterns = [ path('upload/', views.upload, name='upload'), path('get-progress/', views.get_progress, name='get_progress'), # 其他已有路由... ]
4. 进度展示页面的前端实现
创建progress.html,用JavaScript定时轮询进度接口,实时更新页面内容:
<!-- frontend/progress.html --> <!DOCTYPE html> <html> <head> <title>任务处理中</title> </head> <body> <h2>任务进度</h2> <div id="status-text">准备启动任务...</div> <div style="margin: 10px 0;"> <progress id="progress-bar" value="0" max="10"></progress> </div> <script> // 每2秒轮询一次进度接口 const pollInterval = setInterval(() => { fetch('/get-progress/') .then(res => res.json()) .then(data => { // 更新状态文本 document.getElementById('status-text').textContent = data.status; // 更新进度条 document.getElementById('progress-bar').value = data.current; // 任务完成后停止轮询并跳转 if (data.completed) { clearInterval(pollInterval); alert('任务已完成!'); window.location.href = '/upload/'; // 可替换为结果页面地址 } }) .catch(err => console.error('获取进度失败:', err)); }, 2000); </script> </body> </html>
补充说明
- 用session存进度适合小流量场景,高并发场景建议换成Redis等缓存系统,避免session竞争问题。
- 线程方案是快速实现的简便选择,长期扩展建议用Celery+Redis做专业异步任务管理。
- 进度条的
max值要和models.py里的total_steps保持一致,确保显示准确。
内容的提问来源于stack exchange,提问作者Mymy la brute
相关产品推荐
相关产品推荐

