为您的Django/Celery应用程序提供即插即用、可配置、无依赖的进度条。
项目描述
Celery Progress Bars for Django
为您的Django/Celery应用程序提供即插即用、无依赖的进度条。
超级简单的设置。提供大量自定义选项。
演示
Github演示应用程序:为Django构建下载进度条
开始使用Celery可能会有些挑战,eeintech构建了一个完整的Django演示应用程序,并附有一份分步指南,帮助您开始构建自己的进度条!
安装
如果您还没有设置,请确保您已经正确地在项目中设置了celery。
然后安装这个库
pip install celery-progress
使用方法
先决条件
首先在settings.py
中将celery_progress
添加到INSTALLED_APPS
中。
然后添加以下URL配置到您的main urls.py
from django.urls import path, include
urlpatterns = [
# your project's patterns here
...
path(r'^celery-progress/', include('celery_progress.urls')), # add this line (the endpoint is configurable)
]
记录进度
在您的任务中,您应该添加类似以下内容
from celery import shared_task
from celery_progress.backend import ProgressRecorder
import time
@shared_task(bind=True)
def my_task(self, seconds):
progress_recorder = ProgressRecorder(self)
result = 0
for i in range(seconds):
time.sleep(1)
result += i
progress_recorder.set_progress(i + 1, seconds)
return result
您还可以添加可选的进度描述,如下所示
progress_recorder.set_progress(i + 1, seconds, description='my progress description')
显示进度
在调用任务的视图中,您需要像这样获取任务ID
views.py
def progress_view(request):
result = my_task.delay(10)
return render(request, 'display_progress.html', context={'task_id': result.task_id})
然后在您想显示进度条的页面上,您只需执行以下操作。
将以下HTML添加到您想显示进度条的地方
display_progress.html
<div class='progress-wrapper'>
<div id='progress-bar' class='progress-bar' style="background-color: #68a9ef; width: 0%;"> </div>
</div>
<div id="progress-bar-message">Waiting for progress to start...</div>
导入javascript文件。
display_progress.html
<script src="{% static 'celery_progress/celery_progress.js' %}"></script>
初始化进度条
// vanilla JS version
document.addEventListener("DOMContentLoaded", function () {
var progressUrl = "{% url 'celery_progress:task_status' task_id %}";
CeleryProgressBar.initProgressBar(progressUrl);
});
或者
// JQuery
$(function () {
var progressUrl = "{% url 'celery_progress:task_status' task_id %}";
CeleryProgressBar.initProgressBar(progressUrl)
});
显示任务的结果
如果您愿意,您还可以在前端显示任务的结果。
要这样做,请按照以下步骤操作。结果处理也可以自定义。
初始化结果块
这页上渲染结果所需的全部内容。
display_progress.html
<div id="celery-result"></div>
但更有可能的是,您可能想自定义结果的外观,这可以按照以下方式完成
// JQuery
var progressUrl = "{% url 'celery_progress:task_status' task_id %}";
function customResult(resultElement, result) {
$( resultElement ).append(
$('<p>').text('Sum of all seconds is ' + result)
);
}
$(function () {
CeleryProgressBar.initProgressBar(progressUrl, {
onResult: customResult,
})
});
与组一起工作
此库包括对使用Celery组的实验性支持。您可以使用"group_status"
URL端点进行此操作。以下是一个基本示例
示例任务
@shared_task(bind=True)
def add(self, x, y):
return x + y
调用视图
from celery import group
from .tasks import add
def progress_view(request):
task_group = group(add.s(i, i) for i in range(100))
group_result = task_group.apply_async()
# you must explicitly call the save function on the group_result after calling the tasks
group_result.save()
return render(request, 'display_progress.html', context={'task_id': group_result.id})
模板
document.addEventListener("DOMContentLoaded", function () {
var progressUrl = "{% url 'celery_progress:group_status' task_id %}";
CeleryProgressBar.initProgressBar(progressUrl);
});
自定义
initProgressBar
函数接受一个可选的选项对象。以下选项是支持的
选项 | 它的作用 | 默认值 |
---|---|---|
pollInterval | 轮询进度的频率(以毫秒为单位) | 500 |
progressBarId | 覆盖进度条使用的ID | 'progress-bar' |
progressBarMessageId | 覆盖进度条消息使用的ID | 'progress-bar-message' |
progressBarElement | 覆盖进度条使用的元素。如果指定,则忽略progressBarId。 | document.getElementById(progressBarId) |
progressBarMessageElement | 覆盖进度条消息使用的元素。如果指定,则忽略progressBarMessageId。 | document.getElementById(progressBarMessageId) |
resultElementId | 覆盖结果使用的ID | 'celery-result' |
resultElement | 覆盖结果使用的元素。如果指定,则忽略resultElementId。 | document.getElementById(resultElementId) |
onProgress | 当进度更新时调用的函数 | onProgressDefault |
onSuccess | 当进度成功完成时调用的函数 | onSuccessDefault |
onError | 在未指定处理程序的情况下调用已知错误时的函数 | onErrorDefault |
onRetry | 当任务尝试重试时调用的函数 | onRetryDefault |
onIgnored | 当任务结果被忽略时调用的函数 | onIgnoredDefault |
onTaskError | 当进度完成时出错时调用的函数 | onError |
onNetworkError | 网络错误时调用的函数(WebSocket忽略) | onError |
onHttpError | 非200响应时调用的函数(WebSocket忽略) | onError |
onDataError | 调用函数,当响应不是JSON或由于编程错误而具有无效模式时 | onError |
onResult | 当返回非空结果时调用的函数 | CeleryProgressBar.onResultDefault |
barColors | 包含各种进度条状态颜色值的字典。未指定的颜色将使用默认值 | barColorsDefault |
defaultMessages | 包含可以覆盖的默认消息的字典 | 见下文 |
barColors
选项允许您通过传递键值对字典状态: #hexcode
来自定义每个进度条状态的颜色。以下显示默认值。
状态 | 十六进制代码 | 图像颜色 |
---|---|---|
成功 | #76ce60 | |
错误 | #dc4f63 | |
进度 | #68a9ef | |
忽略 | #7a7a7a |
defaultMessages
选项允许您覆盖UI中的某些默认消息。目前这些是
消息ID | 显示时 | 默认值 |
---|---|---|
等待 | 任务等待开始 | '等待任务开始...' |
已开始 | 任务已开始但未报告进度 | '任务已开始...' |
WebSocket支持
此外,此库还提供WebSocket支持,使用Django Channels,由EJH2提供。
一个利用WebSocket的工作示例项目在此处可用。
要使用WebSocket,请使用pip install celery-progress[websockets,redis]
或pip install celery-progress[websockets,rabbitmq]
(根据代理依赖项)进行安装。
请参阅WebSocketProgressRecorder
和websockets.js
以获取详细信息。
保护get_progress端点
默认情况下,任何人都可以通过访问/celery-progress/<task_id>
来查看任何任务的状态和结果
要限制访问,您需要将get_progress()
包装在您自己的视图中,该视图实现权限检查,并创建一个新的URL路由指向您的视图。同时,请确保从您的根URLconf中删除任何现有的(未受保护的)celery进度URL。
例如,使用基于类的视图要求登录
# views.py
from celery_progress.views import get_progress
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import View
class TaskStatus(LoginRequiredMixin, View):
def get(self, request, task_id, *args, **kwargs):
# Other checks could go here
return get_progress(request, task_id=task_id)
# urls.py
from django.urls import path
from . import views
urlpatterns = [
...
path('task-status/<uuid:task_id>', views.TaskStatus.as_view(), name='task_status'),
...
]
使用基于函数的视图要求登录
# views.py
from celery_progress.views import get_progress
from django.contrib.auth.decorators import login_required
@login_required
def task_status(request, task_id):
# Other checks could go here
return get_progress(request, task_id)
# urls.py
from django.urls import path
from . import views
urlpatterns = [
...
path('task-status/<uuid:task_id>', views.task_status, name='task_status'),
...
]
任何指向'celery_progress:task_status'
的链接都需要更改为指向您的新端点。
项目详情
下载文件
下载适合您平台的文件。如果您不确定要选择哪个,请了解更多关于安装包的信息。