You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何在Django OCR应用中使用Celery进度条展示任务进度

如何在Django OCR应用中集成celery-progress-bar展示实时处理进度?

嘿,我帮你一步步搞定这个celery-progress-bar的集成问题!你的OCR流程很清晰,刚好适合用异步任务+实时进度条来优化用户体验——毕竟长时间让用户盯着加载圈太不友好了。下面是具体的实现步骤,完全贴合你给出的代码结构来调整:


第一步:安装依赖与基础配置

首先得把必要的包装起来,同时配置Celery的消息中间件(这里用Redis做示例,你也可以用RabbitMQ):

pip install celery celery-progress redis

然后在你的Django项目settings.py里添加Celery配置:

# settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'  # Redis地址,根据你的实际部署调整
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

第二步:把OCR逻辑迁移到Celery异步任务

因为要实时更新进度,必须把耗时的OCR处理放到Celery异步任务里。新建一个tasks.py文件,把你的处理逻辑移进去,并用celery-progress的ProgressRecorder来更新进度:

# tasks.py
from celery import shared_task
from celery_progress.backend import ProgressRecorder
# 假设你的图像处理、分割、预测函数放在utils.py里,按需调整导入路径
from .utils import image_processing, character_segmentation, predict

@shared_task(bind=True)
def process_ocr_task(self, image_path):
    progress_recorder = ProgressRecorder(self)
    # 先预估总步骤数:图像处理(1步)+字符分割(1步)+每个字符预测(N步)
    total_steps = 2  # 先初始化前两步的计数

    # 1. 图像处理阶段
    cleared_image = image_processing(image_path)
    progress_recorder.set_progress(1, total_steps, description="完成图像处理")

    # 2. 字符分割阶段
    segmented_characters = character_segmentation(cleared_image)
    # 更新总步骤数:加上字符预测的数量
    total_steps += len(segmented_characters)
    progress_recorder.set_progress(2, total_steps, description="完成字符分割,开始识别字符")

    # 3. 逐个字符预测阶段
    predicted = []
    current_step = 2
    for idx, character in enumerate(segmented_characters):
        prediction = predict(character)
        predicted.append(prediction)
        current_step += 1
        progress_recorder.set_progress(
            current_step, 
            total_steps, 
            description=f"正在处理第{idx+1}/{len(segmented_characters)}个字符"
        )

    # 返回最终结果
    return {"predicted_text": "".join(predicted)}

第三步:修改视图触发任务并提供进度查询

调整你的views.py,把原来的同步处理改成触发异步任务,并新增一个接口供前端查询进度:

# views.py
from django.shortcuts import render
from django.http import JsonResponse
from django.conf import settings
import os
from .tasks import process_ocr_task
from celery_progress.backend import Progress

def upload_and_process(request):
    if request.method == 'POST' and request.FILES.get('image'):
        # 先保存上传的图片到媒体目录(确保MEDIA_ROOT配置正确且有写入权限)
        image_file = request.FILES['image']
        temp_image_path = os.path.join(settings.MEDIA_ROOT, 'temp', image_file.name)
        os.makedirs(os.path.dirname(temp_image_path), exist_ok=True)
        
        with open(temp_image_path, 'wb+') as destination:
            for chunk in image_file.chunks():
                destination.write(chunk)
        
        # 触发Celery异步任务
        task = process_ocr_task.delay(temp_image_path)
        # 返回任务ID,前端用这个查询进度
        return JsonResponse({"task_id": task.id})
    
    # GET请求返回上传页面
    return render(request, 'ocr_upload.html')

def get_ocr_progress(request, task_id):
    # 查询任务进度并返回
    progress = Progress(task_id)
    return JsonResponse(progress.get_info())

第四步:前端实现进度条展示

新建一个模板文件ocr_upload.html,实现图片上传、进度条更新和结果展示的逻辑:

<!-- templates/ocr_upload.html -->
<!DOCTYPE html>
<html>
<head>
    <title>OCR文字识别</title>
    <style>
        .progress-container {
            width: 100%;
            height: 24px;
            border: 1px solid #ccc;
            border-radius: 4px;
            margin: 20px 0;
            display: none;
        }
        .progress-bar {
            height: 100%;
            background-color: #4CAF50;
            width: 0%;
            transition: width 0.3s ease;
        }
    </style>
</head>
<body>
    <h1>上传图片进行OCR识别</h1>
    <form id="uploadForm" enctype="multipart/form-data">
        <input type="file" name="image" accept="image/*" required>
        <button type="submit">开始识别</button>
    </form>

    <div class="progress-container" id="progressContainer">
        <div class="progress-bar" id="progressBar"></div>
        <p id="progressText"></p>
    </div>

    <div id="resultArea" style="margin-top: 20px; font-size: 1.2em;"></div>

    <script>
        document.getElementById('uploadForm').addEventListener('submit', async (e) => {
            e.preventDefault();
            const formData = new FormData(e.target);
            
            // 上传图片并获取任务ID
            const uploadRes = await fetch('/upload/', {
                method: 'POST',
                body: formData
            });
            const { task_id } = await uploadRes.json();

            // 显示进度容器
            document.getElementById('progressContainer').style.display = 'block';

            // 轮询查询进度
            const progressInterval = setInterval(async () => {
                const progressRes = await fetch(`/progress/${task_id}/`);
                const progressData = await progressRes.json();

                // 更新进度条和文本
                document.getElementById('progressBar').style.width = `${progressData.percent}%`;
                document.getElementById('progressText').textContent = `${progressData.description} (${progressData.percent}%)`;

                // 任务完成后停止轮询并展示结果
                if (progressData.completed) {
                    clearInterval(progressInterval);
                    document.getElementById('resultArea').textContent = `识别结果:${progressData.result.predicted_text}`;
                }
            }, 500); // 每500毫秒查询一次进度
        });
    </script>
</body>
</html>

最后:配置URL并启动服务

在项目的urls.py里添加对应的路由:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('upload/', views.upload_and_process, name='ocr_upload'),
    path('progress/<str:task_id>/', views.get_ocr_progress, name='ocr_progress'),
]

然后启动必要的服务:

  1. 启动Redis服务(如果用Redis做Broker)
  2. 启动Celery Worker:
celery -A 你的项目名称 worker --loglevel=info
  1. 启动Django开发服务器:
python manage.py runserver

这样用户上传图片后,就能看到实时更新的进度条,体验会好很多!

内容的提问来源于stack exchange,提问作者Harshit Mahajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:48:14