用于处理简单用户通知系统的 Django 信号
Django signals for processing a simple user notification system
我正在学习编码并有一个实时的 Django 项目来保持我的动力。在我的 Django 应用程序中,用户发表评论,而其他人则回复上述评论。
每次用户刷新他们的主页时,我都会计算他们是否收到了关于他们之前留下的评论的任何新回复,如果收到了则显示通知。
这没有扩展性,因为如果用户留下了大量评论并因此收到大量回复,则计算时间比 潜伏者 长创建内容。我想改善这些内容创作者的体验。
阅读 deeper into it,我认为 Django 信号是可行的方法。例如,每次留下新回复时,我可以触发一个 post_save() 信号,该信号可以被接收并为用户更新通知。这样,通知将随着回复的更新而更新——这是应该的方式。
我将不得不重构我的代码,而且我对上面的实现细节仍然一头雾水。谁能给我提供一个快速说明性示例,说明我如何实现上述目标?它会让我开始。
目前,用户回复处理是在我的 views.py class PublicreplyView(CreateView)
中的 CBV 的 form_valid
方法中处理的。我猜我可以在我的 CBV 中包含以下方法吗?
from django.db.models.signals import post_save
post_save.connect(form_valid, sender=User)
然后在其他地方我有一个不同的 CBV,它在每个用户刷新主页后处理通知。我想我需要完全重写吗?就像我说的,我在这方面很模糊。
希望有人指导我如何处理一个说明性的简单示例。谢谢!
p.s。我在 Django < 1.8。
@Djizeus 在他的评论中给出了很好的概述,我会给你一个完整的例子。我会为通知创建单独的模型,并在创建评论时使用 post_save 信号创建它们。但是,我不会挂钩此代码以形成有效但在 Comment 模型上使用 post_save 信号。这样,您就可以更清晰地分离代码。如果您决定拥有例如移动和桌面上的不同形式,或者如果您决定重构 PublicreplyView,您可能不必触摸信号代码。
当您保存评论时,Django 已经触发 post_save 信号,所以您只需要听取它们并处理它们。为此,创建 signals.py 文件:
from django.dispatch import receiver
from django.db.models.signals import post_save
from .models import Comment, Notification
@receiver(post_save, sender=Comment)
def auto_create_notification(sender, instance, created, **kwargs):
if created:
# instance holds the new comment (reply), but you also have to fetch
# original comment and the user who created it
parent_comment = instance.parent_comment
parent_user = parent_comment.user
Notification.objects.create(user=parent_user,
comment=parent_comment,
type="reply_created")
要挂钩此信号,您必须 create/edit 另外两个文件。将此添加到您的 apps.py:
from django.apps import AppConfig
# change Comment with your app name
class CommentConfig(AppConfig):
name = 'comment'
verbose_name = 'Comment'
def ready(self):
import comment.signals
将此添加到您的 __init__.py
:
default_app_config = 'comment.apps.CommentConfig'
关于您的主页视图实现,这取决于您在主页上显示的内容。如果你只显示通知,那么 Notification ListView 是一个不错的选择。如果您混合使用不同的内容,那么我可能会使用 TemplateView 并获取您必须在其 get_context_data() 方法中显示的所有内容。
我正在学习编码并有一个实时的 Django 项目来保持我的动力。在我的 Django 应用程序中,用户发表评论,而其他人则回复上述评论。
每次用户刷新他们的主页时,我都会计算他们是否收到了关于他们之前留下的评论的任何新回复,如果收到了则显示通知。
这没有扩展性,因为如果用户留下了大量评论并因此收到大量回复,则计算时间比 潜伏者 长创建内容。我想改善这些内容创作者的体验。
阅读 deeper into it,我认为 Django 信号是可行的方法。例如,每次留下新回复时,我可以触发一个 post_save() 信号,该信号可以被接收并为用户更新通知。这样,通知将随着回复的更新而更新——这是应该的方式。
我将不得不重构我的代码,而且我对上面的实现细节仍然一头雾水。谁能给我提供一个快速说明性示例,说明我如何实现上述目标?它会让我开始。
目前,用户回复处理是在我的 views.py class PublicreplyView(CreateView)
中的 CBV 的 form_valid
方法中处理的。我猜我可以在我的 CBV 中包含以下方法吗?
from django.db.models.signals import post_save
post_save.connect(form_valid, sender=User)
然后在其他地方我有一个不同的 CBV,它在每个用户刷新主页后处理通知。我想我需要完全重写吗?就像我说的,我在这方面很模糊。
希望有人指导我如何处理一个说明性的简单示例。谢谢!
p.s。我在 Django < 1.8。
@Djizeus 在他的评论中给出了很好的概述,我会给你一个完整的例子。我会为通知创建单独的模型,并在创建评论时使用 post_save 信号创建它们。但是,我不会挂钩此代码以形成有效但在 Comment 模型上使用 post_save 信号。这样,您就可以更清晰地分离代码。如果您决定拥有例如移动和桌面上的不同形式,或者如果您决定重构 PublicreplyView,您可能不必触摸信号代码。
当您保存评论时,Django 已经触发 post_save 信号,所以您只需要听取它们并处理它们。为此,创建 signals.py 文件:
from django.dispatch import receiver
from django.db.models.signals import post_save
from .models import Comment, Notification
@receiver(post_save, sender=Comment)
def auto_create_notification(sender, instance, created, **kwargs):
if created:
# instance holds the new comment (reply), but you also have to fetch
# original comment and the user who created it
parent_comment = instance.parent_comment
parent_user = parent_comment.user
Notification.objects.create(user=parent_user,
comment=parent_comment,
type="reply_created")
要挂钩此信号,您必须 create/edit 另外两个文件。将此添加到您的 apps.py:
from django.apps import AppConfig
# change Comment with your app name
class CommentConfig(AppConfig):
name = 'comment'
verbose_name = 'Comment'
def ready(self):
import comment.signals
将此添加到您的 __init__.py
:
default_app_config = 'comment.apps.CommentConfig'
关于您的主页视图实现,这取决于您在主页上显示的内容。如果你只显示通知,那么 Notification ListView 是一个不错的选择。如果您混合使用不同的内容,那么我可能会使用 TemplateView 并获取您必须在其 get_context_data() 方法中显示的所有内容。