我希望 celery 等待特定任务完成,因此我在 celery 本身旁边安装了 celery-results-backend。但我不明白如何编写任务调用才能等待,因为我当前收到以下错误:
example_task() missing 1 required positional argument: 'user_pk'
Run Code Online (Sandbox Code Playgroud)
视图.py:
def example(request):
user = request.user
if request.method == 'GET':
result = example_taks.apply_async(user_pk=user.pk)
result_output = result.wait(timeout=None, interval=0.5)
return redirect('something')
else:
args = {'user': user}
return redirect(reverse('something'), args)
Run Code Online (Sandbox Code Playgroud)
任务.py:
def example_task(user_pk):
user = User.objects.get(pk=user_pk)
try:
...
Run Code Online (Sandbox Code Playgroud)
之前我是这样称呼这次会谈的:
def example(request):
user = request.user
if request.method == 'GET':
example_task.delay(request.user.pk)
...
Run Code Online (Sandbox Code Playgroud)
这工作正常,但没有等待任务完成。
如果我这样做:
result = allocate_new_bch_address.apply_async(request.user.pk)
Run Code Online (Sandbox Code Playgroud)
我也收到一个错误:
example_task() argument after * must be an iterable, not UUID
Run Code Online (Sandbox Code Playgroud)
小智 10
首先,你用apply_async()
错了。该函数接受打包为元组 (args) 和字典 (kwargs) 的任务参数,如下所示。这是因为您可以指定其他参数来定义任务应如何运行。另一方面,delay()
仅接受任务的 args 和 kwargs。delay()
在大多数情况下就足够了。
您可以这样做:
example_taks.apply_async(kwargs={"user_pk":user.pk})
Run Code Online (Sandbox Code Playgroud)
或这个:
example_tasks.delay(user_pk=user.pk)
Run Code Online (Sandbox Code Playgroud)
您还可以使用位置参数,但我建议尽可能使用 kwargs。
其次,提交异步任务后立即等待它违背了 Celery 的目的。要等待任务完成,您需要对结果调用get() :
result = example_tasks.apply_async(kwargs={"user_pk":user.pk})
result_output = result.get()
Run Code Online (Sandbox Code Playgroud)