通过Celery

时间:2016-05-30 22:43:04

标签: python django celery django-celery celery-task

我有一个模仿Instagram的Django应用程序,用户上传照片或模因,然后他们的粉丝会收到上述照片的通知。

目前,为了发送通知,用户上传照片后,我会遍历上传者拥有的每个粉丝,将通知附加到列表,然后bulk_create对象。如:

    fans = UserFan.objects.filter(star=user).values_list('fan',flat=True)
    fan_list = []
    for fan in fans:
        fan_list.append(PhotoObjectSubscription(viewer_id=fan, which_photo=photo, updated_at=time, seen=False, type_of_object='1'))
    PhotoObjectSubscription.objects.bulk_create(fan_list)

简单的东西。请注意,我的应用程序虚拟机上还安装了supervisord,我通过celeryredis作为消息代理)运行一些基本任务。

现在我想以bulk_create执行上面的celery task任务;异步。我的bulk_create代码位于用于处理照片上传的相同视图中,因此我认为异步执行此操作会加快用户的处理速度。

我是celery任务的新手,所以有人可以通过一个说明性示例指出我如何将上述bulk_create任务转变为celery任务吗?我已经完成了研究,这就是我认为我需要做的事情:

1)在delay()声明的末尾添加bulk_create

PhotoObjectSubscription.objects.bulk_create(fan_list).delay()

2)在tasks.py中,添加一个新任务来处理上述内容:

@task
def bulk_create_notifications():
    PhotoObjectSubscription.objects.bulk_create(fan_list)

3)无需向CELERYBEAT_SCHEDULE中的settings.py添加任何内容,因为任务不是定期任务。

我可能不完全正确,所以请帮忙。

1 个答案:

答案 0 :(得分:3)

您需要传递fans(如果实际上是list),您可能需要将其投放到ValuesListQuerySet以及任务需要的所有其他内容(例如photo.id )作为任务的论据:

@task
def bulk_create_notifications(fans, photo_id):
    fan_list = []
    for fan in fans:
        fan_list.append(PhotoObjectSubscription(viewer_id=fan, which_photo_id=photo_id, updated_at=time, seen=False, type_of_object='1'))
    PhotoObjectSubscription.objects.bulk_create(fan_list)

然后,您可以通过以下方式异步启动任务:

# call delay on the task and pass it the same params you would pass to the fnc itself
bulk_create_notifications.delay(fans)  

由于参数需要由任务队列(redis)存储和传递,因此您只能传递可由您在设置中设置的序列化程序(可能是JSON)序列化的参数。这意味着你应该坚持简单的类型s.a.字符串,整数,您不能将模型实例或其列表作为参数传递。

你当然可以开始更高,只需传递user.id并完成任务中的所有数据库工作。

相关问题