Django模型和celery任务之间存在循环引用问题

9

我正在使用celery来处理django项目。

在celery任务文件中,我需要导入我的模型,以便触发模型方法。 然而,我也希望我的模型能够触发特定的celery任务。

现在,我正在将我的模型导入到celery中,但是尝试将celery任务导入到我的模型文件中会导致循环导入和导入错误。

正确的做法是什么?

4个回答

9
我最终做的是在方法中使用imports,而不是在模型文件顶部进行通用的import。显然,我并不需要循环import。我的问题是在celery任务文件的顶部导入模型,在模型文件的顶部导入celery任务。这并不是必要的。通过将imports分隔开来,我能够避免循环导入的问题。

这种方法在Django用户列表上对于同样的问题经常被提及: https://groups.google.com/forum/#!topic/django-users/1mi7lGxWgvk - cjerdonek
1
这实际上是相当糟糕的模块设计 - 我不确定你的代码库有多大,但如果你在整个代码库中采用这种行为,你将开始遇到真正的问题。你可能需要重新考虑一下你希望你的模型做什么,而你的任务要做什么 - 你想让你的模型能够触发哪些 celery 任务? - wissam

4

Celery提供了send_task()方法,可以通过名称发送任务,从而无需导入它 - 例如:

# models.py
from celery import current_app
# no need to import do_stuff from tasks because it will be sent by name

current_app.send_task('myapp.tasks.do_stuff', args=(1, 'two'), kwargs={'foo': 'bar'})

更多详情请查看文档.


1
不使用tasks.py文件,直接将任务装饰器应用于models.py中的方法,如何?

1
这种方法的缺点是它违反了Celery文档中“使用Django的第一步”部分的建议,例如:“通过上面的行,如果您遵循tasks.py约定,Celery将自动发现可重用应用程序中的任务...”(来自http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html) - cjerdonek
2
哪个更糟糕呢?忽略建议还是在方法内部进行导入?无论如何,修饰符都会被发现吗? - jaywhy13

1
解决这些看似循环依赖的问题的一般方法是将可以被模型和任务同时导入的代码因子化。例如,您可以将提到的模型方法因子化。您的模型将导入这个因子化的代码,任务也会导入它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接