在Django中处理用户触发事件的正确方法是什么?

时间:2018-11-21 06:38:57

标签: python django message-queue

例如,我有一个基于Django的博客,并且已经为用户提供了几种功能:loginedit_profileshare

但是现在我需要实施任务系统。

  1. 用户登录,每天奖励10 score
  2. 用户完成个人资料,奖励20 score
  3. 用户分享我的博客,奖励30 score

我不想将奖励代码与正常功能代码混合使用。因此,我决定使用message queue。伪代码可能类似于:

@login_required
def edit_profile(request):
    user = request.user
    nickname = ...
    desc = ...
    user.save(...)
    action.send(sender='edit_profile', payload={'user_id': user.id})
    return Response(...)

并且奖励可以订阅此操作

@receiver('edit_profile')
def edit_profile_reward(payload):
    user_id = payload['user_id']
    user = User.objects.get(id=user_id)
    mission, created = Mission.objects.get_or_create(user=user, type='complete_profile')
    if created:
         user.score += 20
         user.save()

但是我不知道这是否是正确的方法。如果是这样,我应该使用什么message queuedjango-channel / django-q还是其他? 如果没有,什么是最佳做法?

3 个答案:

答案 0 :(得分:0)

在使用Django或任何Python框架提示任务时,您想要做的事情很正常。尽管没有“正确”的方法来执行此操作,但我个人建议使用Redis。考虑到您将有许多用户获得积分,这将使您的查询真正快速。

您自然可以用Celery弥补这一点,以创建自己的Stack。一切都将在RAM中完成,这将有助于执行此类重复性任务。

您可以看看Redis for Django over here

您基本上需要在设置中将其作为缓存服务器。

在您实施提示的任何文件中,请记住添加以下内容:

from django.core.cache.backends.base import DEFAULT_TIMEOUT
from django.views.decorators.cache import cache_page

我同意最初进行设置似乎令人生畏,但是请相信我,这是快速有效地提示任何任务的好方法。试一试!您会发现它在所有项目中都非常有用。

答案 1 :(得分:0)

对于异步/延迟执行任务/作业,您可以使用

芹菜:https://github.com/celery/celery/

Django: http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html

答案 2 :(得分:0)

如果您正在寻找异步队列,则需要Redis和worker的组合。

RQ Workers

是最常见且最简单的库之一。

实现很简单,但是您需要将rq-workers作为单独的应用程序运行。

它还允许您实现具有不同优先级的不同队列。我将这些用于发送电子邮件或需要更新而无需用户等待(日志等)的事情

Django-Q是另一个很好的解决方案,其优点是可以将当前数据库用作队列-而且还可以与Redis等人一起使用...

最后,Celery是所有人的祖父。您可以使用Celeray进行预定作业,也可以使用异步作业。稍微复杂一点但很好的解决方案。

希望这对您有帮助...