问题描述
我有一个为一家房地产公司创建的 Django 后端。我已经构建了很多硬编码的任务,我想通过管理页面使这些任务可定制......但我不太清楚如何做到这一点。
例如,假设我想创建一个任务来发送可以从管理页面自定义的电子邮件。理想情况下,我有一个触发器列表可供选择,例如提交联系表单。
看起来像这样:
解决方法
我在很多场合都有同样的需求,解决方法如下:
- 我有一个抽象的“基本”任务模型,其中包含一些与任何“通用”后台任务通用的字段:created_on、started_on、completed_on、status、progress、failure_reason 等等
- 当需要新的特定任务时,我会写:
- 由调度程序(在您的情况下为 Celery)运行的作业功能
- 从 Task 派生的具体模型
- 派生模型知道必须运行哪个作业;这是在模型定义中硬编码的; 我还添加了特定字段以收集作业所需的任何自定义参数
- 现在,您可以通过编程方式或从 Django 管理员创建新任务,根据需要提供实际参数;在后一种情况下,Django 照常提供所需的表单和验证
在数据库中保存新记录后,模型开始工作,传递任务(模型)id; 您可以从作业中检索任务的详细信息:这是原始问题的答案。 您还可以更新模型中的进度/状态以供以后检查,并使用基类提供的其他服务(例如,日志记录)。
该模式已被证明非常有用,因为作为一个额外的好处,您可以从 Django 管理员监控异步任务。
在多个项目中使用了它,我将此逻辑封装在一个可重用的 Django 应用程序中:
https://github.com/morlandi/django-task
当前的实现基于 rq
,因为 Celery
是针对我的需求过度设计的。我想它可以通过一些修改适应 Celery
:
- 删除 Task.check_worker_active_for_queue()
- 移除 Task.get_queue()
- 重构 Task.run()
另外,辅助Job类必须重构如下:
- 将 rq.get_current_job() 替换为 Celery 的等效项
很遗憾,我最近没用过 Celery,所以无法给出更详细的建议。