将进度返回到 Django 中每个值更改的模板

Posted

技术标签:

【中文标题】将进度返回到 Django 中每个值更改的模板【英文标题】:Return the progress to the template each value change in Django 【发布时间】:2020-02-17 05:49:34 【问题描述】:

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

我有一个函数的 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 的值。有什么简单的方法可以使用芹菜或其他东西来做到这一点

【问题讨论】:

【参考方案1】:

你不能在不结束请求的情况下显示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)

您的流程将是,对create_taskstatus 进行ajax 调用并使用返回的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 channels 或 centrifugo 将更新推送到用户套接字连接中的通道,但如果您只需要此功能,我不会尝试,开销很大这里只是为了这个。

【讨论】:

以上是关于将进度返回到 Django 中每个值更改的模板的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:如何根据滚动视图的用户当前滚动位置同步/更改进度条进度?

值更改时如何在 UIKit 中更新 SwiftUI 视图?

Django-Celery 进度条

五班二组web测试实践进度

带有进度通知的长时间运行的后台任务

关于前端video标签视频无法拖动进度条快进问题(Django)