无法从 Django 应用程序调用芹菜任务(缺少位置参数)

Posted

技术标签:

【中文标题】无法从 Django 应用程序调用芹菜任务(缺少位置参数)【英文标题】:Celery task cannot be called (missing positional arguments) from Django app 【发布时间】:2019-07-21 19:24:03 【问题描述】:

好的,我已经翻遍了所有的 SO 帖子、Celery 文档等……我就是想不通。无论我尝试什么或如何尝试从 Django 应用程序调用任务,Celery 都会抱怨我没有提供所需的参数。

“TypeError: add() 缺少 2 个必需的位置参数:'x' 和 'y'”。

我从他们的文档中遵循了一个非常简单的示例...仅使用延迟,例如:

add.delay(1, 2)

仍然是同样的错误。我还尝试了add.delay(x=1, y=2)celery.send_task("add", [1, 2]) 以及其他各种我在各种帖子中看到任务调用的方法,但它们都不起作用。

方法很简单:

@shared_task
def add(x, y):
    return x + y

我也试过命名,比如:

@task(name="my_add")
def add(x, y):
    return x + y

同样的结果。我还可能缺少什么?

【问题讨论】:

【参考方案1】:

首先,您应该在与您的 Django 和 Celery 配置相关的帖子中添加更多信息。

但我认为您的错误在于 @task 装饰器,因为您似乎需要使用 绑定任务

绑定的任务意味着该任务的第一个参数将始终 是任务实例(self),就像 Python 绑定的方法一样。 Reference。 另一方面,bind 参数意味着该函数将是一个“绑定方法”,以便您可以访问任务类型实例上的属性和方法。 Reference

所以你的代码应该是这样的:

import celery

@task(bind=True, name="my_add")
def add(self, x, y):
    return x + y

请注意,任务装饰器的 bind 参数将允许访问 self(任务类型实例)。

最后我建议你再次查看Celery setup on Django。

【讨论】:

很好的答案。我遇到了同样的问题,这解决了它。不过,我不明白为什么:如果不绑定方法,似乎我应该能够装饰一个函数并传入 args。在我的情况下,对 self 的引用是不必要的。我正在使用烧瓶。 这解决了我的问题,我一个接一个地使用@classmethod 然后@celery.task()。我认为 celery 无法获得 cls 参数。也许,bind=True 为任务提供了 cls (or self) 参数。

以上是关于无法从 Django 应用程序调用芹菜任务(缺少位置参数)的主要内容,如果未能解决你的问题,请参考以下文章

芹菜 - 无法获取任务结果

带有芹菜的Django:计划任务(ETA)并行执行多次

芹菜任务没有注册?

芹菜节拍不接周期性任务

如何在 Django 中等待芹菜任务的结果

芹菜登录 Django