【问题标题】:How to update progress bar while making a Django Rest api request?如何在发出 Django Rest api 请求时更新进度条?
【发布时间】:2017-03-08 12:29:56
【问题描述】:

我的 django rest 应用程序接受请求以抓取多个页面的价格并进行比较(这需要大约 5 秒的时间),然后将每个页面的价格列表作为 json 对象返回。 我想用当前操作更新用户,例如,如果我抓取 3 个页面,我想像这样更新界面: 搜索 1/3 搜索 2/3 搜索 3/3 我怎样才能做到这一点? 我在前端使用 Angular 2,但这不应该有很大的不同,因为它是一个后端问题。

【问题讨论】:

  • 您是否使用后端中的任何标志来跟踪页数?并编辑您的问题以添加您正在使用的模型和视图。这将有助于更好地调试。
  • 我的后端循环遍历 url 列表并获取价格。我会尽快添加模型

标签: django django-rest-framework


【解决方案1】:

这不是唯一的方法,但这就是我在 Django 中的做法。


你需要的东西

异步工作进程

这允许您在请求-响应周期的上下文之外进行工作。最常见的是django-rqCelery。我推荐 django-rq 的简单性,特别是如果你正在实现的只是一个进度指示器。

缓存层(可选)

虽然在这种情况下您可以使用数据库进行持久化,但临时缓存键值存储在这里更有意义,因为进度信息是短暂的。 Memcached 后端内置在 Django 中,但是我建议切换到 Redis,因为它功能更全面、速度超快,并且由于它位于 Django 的缓存抽象背后,因此不会增加复杂性。 (这也是使用上面django-rq工作进程的要求)


实施

概述

基本上,我们将向服务器发送一个请求以启动异步工作器,并轮询一个不同的进度指示器端点,该端点提供该工作器的当前进度状态,直到它完成(或失败)。

服务器端

  1. 将您想要跟踪进度的函数重构为异步任务函数(在 django-rq 的情况下使用 @job 装饰器)

  2. 初始的POST端点应该首先生成一个随机的唯一ID来识别请求(可能是uuid)。然后,将 POST 数据连同这个唯一 ID 传递给异步函数(在 django-rq 中,这看起来像 function_name.delay(payload, unique_id))。由于这是一个异步调用,解释器不会等待任务完成并立即继续。返回带有包含唯一 ID 的 JSON 负载的 HttpResponse。

  3. 回到异步函数,我们需要使用缓存设置进度。在函数的最顶部,我们应该添加一个cache.set(unique_id, 0) 以表明到目前为止进展为零。使用您自己的数学实现,随着进度接近 100% 完成,将此值更改为更接近 1。如果由于某种原因操作失败,您可以将其设置为-1

  4. 创建一个新端点以供浏览器轮询以检查进度。这会查找unique_id 查询参数并使用它来查找cache.get(unique_id) 的进度。返回一个带有进度量的 JSON 对象。

客户端

  1. 发送操作的 POST 请求并接收响应后,该响应应包含 unique_id。立即开始定期轮询进度端点,将unique_id 设置为查询参数。使用setInterval() 时,间隔可能类似于 1 秒,如果仍有待处理的请求,则使用逻辑阻止发送新请求。

  2. 当收到的进度等于1(或-1失败)时,您知道该过程已完成,您可以停止轮询


就是这样!仅仅为了获得进度指标就需要做一些工作,但是一旦你完成了它,在其他项目中重用该模式就会容易得多。

另一种我没有探索过的方法是通过 Webhooks/Channels。这样就不需要轮询了,服务器直接将消息发送给客户端。

【讨论】:

    猜你喜欢
    • 2021-10-05
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2022-01-01
    相关资源
    最近更新 更多