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

What is the proper way to process the user-trigger events in Django?

比如我有一个基于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 还是别的? 如果不是,最佳做法是什么?

当涉及到使用 Django 或任何 Python 框架的提示任务时,您正在寻求做的是相当正常的。虽然没有 "right" 方法可以做到这一点,但我个人建议使用 Redis。考虑到您会有很多用户获得积分,这将使您的查询非常快。

你自然可以用 Celery 来制作你自己的 Stack。一切都将在内存中完成,这将有助于此类重复性任务。

你可以看看Redis for Django over here

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

无论您在哪个文件中实现提示,请记住添加以下内容:

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

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

对于 asynchronous/deferred 执行 tasks/jobs 你可以使用

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

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

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

最常见、最简单的库之一是 RQ Workers

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

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

Django-Q 是另一个很好的解决方案,其优点是能够将当前数据库用作队列 - 但也适用于 Redis 等...

最后,Celery 是他们所有人的爷爷。您可以使用 Celeray 安排作业以及异步作业。有点复杂但很好的解决方案。

希望这对您有所帮助...