Django:标记为已读“通知”

2024-01-08

我正在做一个学校项目。现在任何用户都可以提出问题。

为了在任何用户提出问题时通知所有用户,我创建了一个新应用程序,并在提出问题时通过简单的“视图”通知他们。但这还只是普通的通知。

用户打开“通知”选项卡后,如何将它们标记为已读?就像在社交网络上一样!


我建议你使用ContentType https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#django.contrib.contenttypes.models.ContentType为任何模型发出动态通知。下面的代码片段是如何实现的示例通知系统;

1. 在你的models.py

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.utils.translation import ugettext_lazy as _


class ContentTypeToGetModel(object):

    """
    requires fields:
        - content_type: FK(ContentType)
        - object_id: PositiveIntegerField()
    """

    def get_related_object(self):
        """
        return the related object of content_type.
        eg: <Question: Holisticly grow synergistic best practices>
        """
        # This should return an error: MultipleObjectsReturned
        # return self.content_type.get_object_for_this_type()
        # So, i handle it with this one:
        model_class = self.content_type.model_class()
        return model_class.objects.get(id=self.object_id)

    @property
    def _model_name(self):
        """
        return lowercase of model name.
        eg: `question`, `answer`
        """
        return self.get_related_object()._meta.model_name


class Notification(models.Model, ContentTypeToGetModel):
    # sender = models.ForeignKey(
    #    User, related_name='notification_sender')

    receiver = models.ForeignKey(
        User, related_name='notification_receiver')

    content_type = models.ForeignKey(
        ContentType, related_name='notifications', on_delete=models.CASCADE)

    object_id = models.PositiveIntegerField(_('Object id'))
    content_object = GenericForeignKey('content_type', 'object_id')

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    STATUS_CHOICES = (
        ('reply', _('a reply')),
        ('comment', _('a comment')),
        ('message', _('a message'))
    )
    status = models.CharField(
        _('Status'), max_length=20,
        choices=STATUS_CHOICES, default='comment')

    is_read = models.BooleanField(
        _('Is read?'), default=False)

    def __str__(self):
        title = _('%(receiver)s have a %(status)s in the %(model)s:%(id)s')
        return title % {'receiver': self.receiver.username, 'status': self.status,
                        'model': self._model_name, 'id': self.object_id}

    class Meta:
        verbose_name_plural = _('notifications')
        ordering = ['-created']

2. 在你的views.py

from django.views.generic import (ListView, DetailView)
from yourapp.models import Notification


class NotificationListView(ListView):
    model = Notification
    context_object_name = 'notifications'
    paginate_by = 10
    template_name = 'yourapp/notifications.html'

    def get_queryset(self):
        notifications = self.model.objects.filter(receiver=self.request.user)

        # mark as reads if `user` is visit on this page.
        notifications.update(is_read=True)
        return notifications

3.在你的yourapp/notifications.html

{% extends "base.html" %}

{% for notif in notifications %}
  {{ notif }}

  {# for specific is like below #}
  {# `specific_model_name` eg: `comment`, `message`, `post` #}
  {% if notif._model_name == 'specific_model_name' %}
    {# do_stuff #}
  {% endif %}
{% endfor %}

那么,当我创建该通知时?例如:当其他用户发送评论到receiver在这个帖子上。

from django.contrib.contenttypes.models import ContentType

def send_a_comment(request):
    if request.method == 'POST':
        form = SendCommentForm(request.POST)
        if form.is_valid():
            instance = form.save(commit=False)
            #instance.sender = request.user
            ...
            instance.save()

            receiver = User.objects.filter(email=instance.email).first()
            content_type = ContentType.objects.get(model='comment')

            notif = Notification.objects.create(
                receiver=receiver,
                #sender=request.user,
                content_type=content_type,
                object_id=instance.id,
                status='comment'
            )
            notif.save()

怎么样menu?喜欢这个 stackoverflow、facebook、instagram 还是其他?

您可以使用模板标签来处理它,例如:

# yourapp/templatetags/notification_tags.py

from django import template

from yourapp.models import Notification

register = template.Library()

@register.filter
def has_unread_notif(user):
    notifications = Notification.objects.filter(receiver=user, is_read=False)
    if notifications.exists():
        return True
    return False

and the navs.html menu:

{% load notification_tags %}

{% if request.user.is_authenticated %}
  <ul class="authenticated-menu">
    <li>
        <a href="/notifications/">
          {% if request.user|has_unread_notif %}
            <i class="globe red active icon"></i>
          {% else %}
            <i class="globe icon"></i>
          {% endif %}
        </a>
    </li>
  </ul>
{% endif %}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django:标记为已读“通知” 的相关文章

随机推荐

  • 关于集成测试类的 Spring 配置文件

    我们有由 java 测试类运行的 selenium 测试 在本地环境中一切正常 但我想在詹金斯上运行时关闭这些测试 所以我用 RunWith SpringJUnit4ClassRunner class SpringApplicationCo
  • JSON 中的单引号与双引号

    My code import simplejson as json s username dfdsfdsf 1 s username dfdsfdsf 2 j json loads s 1定义是错误的 2定义是正确的 我听说在Python中
  • MySQL:删除所有超过 20 小时的行

    我的表中有一个时间戳字段 如何删除超过 20 小时的记录 我的查询是 DELETE FROM tickets WHERE timestamp lt NOW INTERVAL 20 HOUR 问题 以上查询是否正确 是的 你的delete查询
  • 在允许 DTD 加载之前检查是否存在恶意 XML?

    从 libxml 2 9 开始 解析 XML 时已禁用加载外部实体 以防止XXE 攻击 http websec io 2012 08 27 Preventing XEE in PHP html 在这种情况下 为了能够在使用 PHP 的 DO
  • Android 版 iOS Quick Look 框架

    有没有类似的东西iOS 快速查看框架 http developer apple com library ios documentation QuickLook Reference QuickLookFrameworkReference iP
  • 如何避免 as.numeric() 中的“警告消息:强制引入的 NA”[重复]

    这个问题在这里已经有答案了 我有一个关于如何避免的问题NA使用时as numericR 中的函数 正如你在下面看到的 我有一个字符变量 但它的值是数字 cumulative viewers 我想通过将其转换为数字as numeric但它不能
  • 根据 Scala 语言规范,包是 AnyRef 值并且具有类型。这有什么意义呢?

    我正在通读 Scala 语言规范 并且遇到了一些令人困惑的事情 即 以下含义 包是值并且它们确实有类型 以下是我从 Scala 语言规范中得出的这个奇怪事实的结论 也许是错误的 背景 In the 类型指示符 http www scala
  • 将查询结果附加到 PostgreSQL 中的同一结果行 - Redshift

    我有一个表 有 3 列 A B C 其中 A 不是主键 我们需要为每个不同的 A 按 A 分组 选择 B C 对 并将结果附加到最终结果集的末尾 这在sql中可能吗 A B C a1 b1 c1 a1 b2 c2 a1 b3 c3 a2 b
  • 从 NSKeyedArchiver 加载 Singleton 的状态

    我有一个类 我已经将其制作成单例 并且能够使用 NSKeyedArchiver 保存它的状态 但是我无法将其状态拉出来 在我执行加载的函数中 Venue venue Venue sharedVenue NSData data NSMutab
  • 将所有连字符类型替换为 ascii 连字符“-”

    有没有办法用简单的 ASCII 替换所有类型的连字符 我正在寻找类似的适用于空间的东西 txt re sub r s txt 我相信一些非 ASCII 连字符避免了删除某些特定停用词 由连字符连接的项目名称 的正确过程 例如 我想用 AR
  • 创建顺序计数器,根据面板数据组内的条件重新启动[重复]

    这个问题在这里已经有答案了 我有一个面板数据集 我想为其创建一个计数器 该计数器随着面板中的每个步骤而增加 但每当发生某些情况时就会重新启动 就我而言 我使用的是国家 地区年份数据 并且想要计算事件之间的年份间隔 这是一个玩具数据集 其中包
  • 有浏览器实现了 DOM3 EventListenerList 吗?

    早在 2010 年 3 月 答案就是 不 浏览器事件监听器列表实现 https stackoverflow com questions 2424737 browser eventlistenerlist implementation 我想知
  • Python 相当于 LINQ All 函数?

    测试集合中的所有元素是否满足条件的惯用 Python 方法是什么 这 NET All method http msdn microsoft com en us library bb548541 aspxC 很好地填补了这个空白 有一个明显的
  • 在错误的位置包含标题 Laravel 4

    我试图首先包含 header blade php 然后包含内容 但它包含错误的方式 include site components header yield content include site components footer 渲染
  • Android 4.0 模拟器无法启动

    当尝试创建并启动 Android 4 0 模拟器时 我获得了 Android 模拟器皮肤 但操作系统似乎无法启动 我已从 Android SDK 管理器安装了 ARM EABI v7 软件包 尝试创建模拟器 但收到有关缺少 userdata
  • 正则表达式匹配不相等或不反转的数字组

    我在这里指的是这个问题的后续 正则表达式匹配两个不相等的数字 https stackoverflow com questions 5257685 regular expression to match two numbers that ar
  • Swift 3 / iOS 10 / TodayExtension - UserDefaults 始终返回 nil

    这是我在这个网站上的第一个问题 我有一个无法解决的问题 我正在开发一个带有 Today 扩展的简单笔记应用程序 我在 Swift 2 2 和 iOS 9 中没有遇到任何问题 问题只出现在 iOS 10 上的 Swift 2 3 和 Swif
  • 从 Python 访问 COM 方法

    我有一个旧的 Windows DLL 没有源代码 它实现了实用函数表 几年前 计划将其转换为 COM 对象 以便实现 IUnknown 接口 为了使用这个 DLL 有一个头文件 简化的 interface IFunctions public
  • 在编写 C 代码时如何优雅地利用 REV 和 RBIT 等 ARM 指令?

    我正在编写可以为 Arm Cortex M3 微控制器编译的 C 代码 该微控制器支持多种有用的指令 可有效操作寄存器中的位 包括 REV RBIT SXT 在编写C代码时 如果我需要那些特定的功能 如何利用这些指令 例如 我怎样才能完成这
  • Django:标记为已读“通知”

    我正在做一个学校项目 现在任何用户都可以提出问题 为了在任何用户提出问题时通知所有用户 我创建了一个新应用程序 并在提出问题时通过简单的 视图 通知他们 但这还只是普通的通知 用户打开 通知 选项卡后 如何将它们标记为已读 就像在社交网络上