首页 > 解决方案 > 将进度返回到 Django 中每个值更改的模板

问题描述

我想在后端显示任务的进度,以便让用户知道工作仍在进行中。

我有一个函数的ajax调用来获取最终值。在后端完成这项工作需要很多时间,但每次我在一个变量中获得工作进度时,我都想在前端显示这个变量的值。

例如我的ajax函数是

def ajax_call(request):
    j = 0
    for i in range(1,10000):
        j += i
    res = {'data': j}
    return JsonResponse(res, safe=False)

正如我们所知,它将返回 j 的最终值。但我想在每次更改的前端显示 j 的值。有没有什么简单的方法可以使用芹菜或其他东西来做到这一点

标签: djangoajaxpython-3.xdjango-templates

解决方案


你不能在j不结束请求的情况下显示每个值,因此,结束进程本身。

但是,您可以做一些变通方法,例如在某个模型中使用状态字段来从那里获取该值并将其传递给您的用户,这应该适用于 celery 任务或其他任何东西。

一些简单的代码(未测试)

在你的models.py

class TaskStatus(models.Model):
    STATUS_ONEPERCENT = 'zeropct'
    STATUS_ONEPERCENT = 'onepct'
    STATUS_TENPERCENT = 'tenpct'
    CHOICES_STATUS = (
        (STATUS_ZEROPERCENT, _('0%')),
        (STATUS_ONEPERCENT, _('1%')),
        (STATUS_TENPERCENT, _('10%')),
    )
    user = models.ForeignKey(
        get_user_model(), 
        verbose_name=_('User task owner'),
        related_name='tasks_statuses')
    task_uuid = models.CharField(verbose_name=_('Taks unique ID'), maxlength=50)
    status = models.CharField(
        verbose_name=_('Task status'), 
        choices=CHOICES_STATUS, 
        default=CHOICES_STATUS[0][0])

在你看来

def create_taskstatus(request):
    newts = TaskStatus.objects.create(
        user=request.user,
        task_uuid=uuid.uuid1())
    res = {
        'tsuuid': newts.task_uuid,
        'status': newts.status, 
        'status_hr': newts.get_status_display()  # human readable status
    }
    return JsonReponse(res, safe=False)

def get_taskstatus(request, tsuuid):
    user_task = get_user_model().tasks_statuses.get(task_uuid=tsuuid)
    res = {
        'tsuuid': user_task.task_uuid, 
        'status': user_task.status, 
        'status_hr': user_task.get_status_display()  # human readable status
    }
    return JsonReponse(res, safe=False)

您的流程将是,进行 ajax 调用create_taskstatus并使用返回tsuuid来查询定期调用get_taskstatus查看的任务的状态,在这里要小心,如果您经常调用它可能会使您的服务器过载。

您当前的任务代码必须接收任务 uuid 并负责更新TaskStatus.status值,以便根据需要更新它:

def ajax_call(request, taskuuid):
    user_task = get_user_model().tasks_statuses.get(task_uuid=tsuuid)
    j = 0
    for i in range(1,10000):
        j += i
        if j == 100:
            user_task.status = TaskStatus.STATUS_ONEPERCENT
            user_task.save()
        elif j == 1000:
            user_task.status = TaskStatus.STATUS_TENPERCENT
            user_task.save()
    res = {'data': j}
    return JsonResponse(res, safe=False)

这只是一种方法,您必须调整代码以满足您的需求,我只是希望这能推动您找到解决方案。


另一方面,您可以利用 websockets 并使用django 通道centrifugo将更新推送到用户套接字连接中的通道,但如果您只需要此功能,我不会尝试,这里有很多开销。


推荐阅读