在 Django 中处理用户触发事件的正确方法是什么?
What is the proper way to process the user-trigger events in Django?
比如我有一个基于Django
的博客,我已经有几个功能供用户使用:login
、edit_profile
、share
.
但是现在我需要实现一个任务系统
- 用户登录,每天奖励
10 score
- 用户完成个人资料,奖励
20 score
- 用户分享我的博客,打赏
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 queue
? django-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 安排作业以及异步作业。有点复杂但很好的解决方案。
希望这对您有所帮助...
比如我有一个基于Django
的博客,我已经有几个功能供用户使用:login
、edit_profile
、share
.
但是现在我需要实现一个任务系统
- 用户登录,每天奖励
10 score
- 用户完成个人资料,奖励
20 score
- 用户分享我的博客,打赏
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 queue
? django-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 安排作业以及异步作业。有点复杂但很好的解决方案。
希望这对您有所帮助...