我有一个模仿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
,我通过celery
(redis
作为消息代理)运行一些基本任务。
现在我想以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
添加任何内容,因为任务不是定期任务。
我可能不完全正确,所以请帮忙。
答案 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
并完成任务中的所有数据库工作。