【问题标题】:Django signals for processing a simple user notification system用于处理简单用户通知系统的 Django 信号
【发布时间】:2016-09-02 23:53:28
【问题描述】:

我正在学习编码并有一个实时的 Django 项目来保持我的动力。在我的 Django 应用程序中,用户离开 cmets,而其他人则回复所述 cmets。

每当用户刷新他们的主页时,我都会计算他们是否收到了关于他们之前离开的 cmets 的任何新回复,如果收到了则显示通知。

这不会扩展,因为如果用户留下了大量的 cmets 并因此收到了大量的回复,那么计算时间会比不创建内容的 潜伏者 更长。我想改善这些内容创作者的体验。

阅读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,一旦他们刷新主页,它就会为每个用户处理通知。我想我需要完全重写它?就像我说的,我在这方面很模糊。

希望有人指导我如何处理一个说明性的简单示例。谢谢!


附言我在 Django

【问题讨论】:

  • 这是一个很好的问题,但它的范围很广,可能对 SO 来说太宽泛了。阅读您对问题的描述,听起来您缺少一些东西:如果您不想在每次显示页面时计算通知,则必须存储它们。这意味着在您的 post_save 中,在数据库中的某处存储/更新用户的通知。当他看到主页时,更新(减少)数据库中的相同值。
  • @Djizeus:我如何将post_save 用于CBV 的form_valid 方法。对吗?

标签: django django-views django-signals


【解决方案1】:

@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")

要挂钩此信号,​​您​​必须再创建/编辑两个文件。将此添加到您的 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() 方法中显示的所有内容。

【讨论】:

    猜你喜欢
    • 2012-02-11
    • 2017-08-09
    • 1970-01-01
    • 2013-05-24
    • 2013-07-30
    • 2011-05-12
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    相关资源
    最近更新 更多