用于处理简单用户通知系统的 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() 方法中显示的所有内容。