今天用django+celery实现异步时出现以下bug:

开启异步任务:generate_static_sku_detail_html.delay(obj.id)
调用:celery_tasks.html.tasks.generate_static_sku_detail_html(self,sku_id)
函数时,如果不传参数self,就报错。
Traceback (most recent call last):
File "/home/python/.virtualenvs/py3_first_django_project/lib/python3.5/site-packages/celery/app/trace.py", line 382, in trace_task
R = retval = fun(*args, **kwargs)
File "/home/python/.virtualenvs/py3_first_django_project/lib/python3.5/site-packages/celery/app/trace.py", line 641, in __protected_call__
return self.run(*args, **kwargs)
TypeError: generate_static_sku_detail_html() takes 1 positional argument but 2 were given


加上self不报错,可以实现异步任务。

在终端执行测试命令也不会报错,异步任务可以执行,不会报错。
for sku in SKU.objects.all():
...: generate_static_sku_detail_html.delay(sku.id)


不开启异步任务,直接调用generate_static_sku_detail_html()函数,不会报错,而且可以运行成功。

 

虽然加上slelf,可以实现功能,但是还是不知道为什么要加self。

经过不断地修改,调试终于找到了,根本问题所在。

因为在定义generate_static_sku_detail_html函数时,使用了装饰器,并且bind=True,

@app.task(bind=True,name='generate_static_sku_detail_html')
def generate_static_sku_detail_html(self,sku_id):

  pass

总结:如果要开启异步任务,使用装饰器task时,参数bind=True,定义函数时,就一定需要加上self,

如果不写参数bind,默认bind=False,定义函数就不用加上self。