今天用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。