跳转到主要内容

Django的GitHub通知类似应用程序。

项目描述

django-notifications 文档

build-status Coverage Status

django-notifications 是一个类似于 GitHub 通知的 Django 应用,它是由 django-activity-stream 演变而来的

django-notificationsdjango-activity-stream 之间的主要区别

  • django-notifications 用于构建类似于 GitHub "通知" 的功能
  • django-activity-stream 用于构建 GitHub "动态" 功能

通知实际上是动作事件,它们由四个主要组件分类。

  • Actor。执行活动的对象。
  • Verb。标识活动动作的动词短语。
  • Action Object(可选) 与动作本身相关联的对象。
  • Target(可选) 活动执行的对象。

ActorAction ObjectTarget 是指向任何任意 Django 对象的 GenericForeignKeys。一个动作是描述某个 Actor 在某个时间点对某个可选的 Target 执行了什么动作 (Verb),并导致 Action Object 被创建/更新/删除的描述。

例如: justquick (actor) closed (verb) issue 2 (action_object) on activity-stream (target) 12 hours ago

本规范的命名法基于 Activity Streams 规范: http://activitystrea.ms/specs/atom/1.0/

要求

  • Python 3.7, 3.8, 3.9, 3.10, 3.11
  • Django 3.2, 4.0, 4.1

安装

使用 pip 安装非常简单,并将安装所有必需的库。

$ pip install django-notifications-hq

或从源代码获取

$ git clone https://github.com/django-notifications/django-notifications
$ cd django-notifications
$ python setup.py sdist
$ pip install dist/django-notifications-hq*

请注意,将安装 django-model-utils:这是传递查询集管理器所必需的。

然后,要将 Django Notifications 添加到您的项目中,请将应用程序 notifications 添加到您的 INSTALLED_APPS 和 urlconf 中。

该应用程序应放在将生成通知的所有应用程序之后,例如 django.contrib.auth

INSTALLED_APPS = (
    'django.contrib.auth',
    ...
    'notifications',
    ...
)

将通知 URL 添加到您的 urlconf 中

import notifications.urls

urlpatterns = [
    ...
    url('^inbox/notifications/', include(notifications.urls, namespace='notifications')),
    ...
]

安装这些 URL 的方法,即导入而不是使用 'notifications.urls',是为了确保 URL 在 notifications 命名空间中安装。

要运行模式迁移,请执行 python manage.py migrate notifications

生成通知

最好在单独的信号中生成通知。

from django.db.models.signals import post_save
from notifications.signals import notify
from myapp.models import MyModel

def my_handler(sender, instance, created, **kwargs):
    notify.send(instance, verb='was saved')

post_save.connect(my_handler, sender=MyModel)

要在代码的任何地方生成通知,只需导入通知信号,并用您的执行者、接收者和动词发送它。

from notifications.signals import notify

notify.send(user, recipient=user, verb='you reached level 10')

完整的语法是。

notify.send(actor, recipient, verb, action_object, target, level, description, public, timestamp, **kwargs)

参数

  • actor:任何类型的对象。 (必需) 注意:如果您打算使用关键字参数,请使用 sender 而不是 actor
  • recipient:一个 Group 或一个 User QuerySet 或一个 User 的列表。 (必需)
  • verb:一个字符串。 (必需)
  • action_object:任何类型的对象。 (可选)
  • target:任何类型的对象。 (可选)
  • level:Notification.LEVELS 之一 ('success', 'info', 'warning', 'error') (默认=info)。 (可选)
  • description:一个字符串。 (可选)
  • public:一个布尔值 (默认=True)。 (可选)
  • timestamp:一个 tzinfo (默认=timezone.now())。 (可选)

额外数据

您可以通过以下方式将任意数据附加到通知中

  • 在您的 settings.py 中添加: DJANGO_NOTIFICATIONS_CONFIG = { 'USE_JSONFIELD': True}

然后,您传递给 notify.send(...) 的任何额外参数都将附加到通知对象的 .data 属性。这些将使用 JSONField 的序列化器进行序列化,因此您可能需要考虑这一点:仅使用可序列化的对象是个好主意。

软删除

默认情况下,delete/(?P<slug>\d+)/ 从数据库中删除指定的通知记录。您可以通过以下方式将此行为更改为“将 Notification.deleted 字段标记为 True”:

  • 在您的 settings.py 中添加:DJANGO_NOTIFICATIONS_CONFIG = { 'SOFT_DELETE': True}

使用此选项,QuerySet 方法 unreadread 包含一个额外的过滤器:deleted=False。同时,QuerySet 方法 deletedactivemark_all_as_deletedmark_all_as_active 被启用。有关详细信息,请参阅 QuerySet 方法部分。

API

QuerySet 方法

使用 django-model-utils,我们不仅可以将查询集方法添加到管理器中,还可以添加到所有将使用的查询集中,包括相关对象。这使得我们能够执行诸如

    Notification.objects.unread()

返回所有未读通知的操作。要为单个用户执行此操作,我们可以这样做

    user = User.objects.get(pk=pk)
    user.notifications.unread()

还有其他一些 QuerySet 方法。

qs.unsent()

返回所有未发送的通知,同时过滤当前查询集。(emailed=False)

qs.sent()

返回所有已发送的通知,同时过滤当前查询集。(emailed=True)

qs.unread()

返回所有未读通知,同时过滤当前查询集。当 SOFT_DELETE=True 时,此过滤器包含 deleted=False

qs.read()

返回所有已读通知,同时过滤当前查询集。当 SOFT_DELETE=True 时,此过滤器包含 deleted=False

qs.mark_all_as_read() | qs.mark_all_as_read(recipient)

将查询集中的所有未读通知(可选地也按 recipient 过滤)标记为已读。

qs.mark_all_as_unread() | qs.mark_all_as_unread(recipient)

将查询集中的所有已读通知(可选地也按 recipient 过滤)标记为未读。

qs.mark_as_sent() | qs.mark_as_sent(recipient)

将查询集中的所有未发送通知(可选地也按 recipient 过滤)标记为已发送。

qs.mark_as_unsent() | qs.mark_as_unsent(recipient)

将查询集中的所有已发送通知(可选地也按 recipient 过滤)标记为未发送。

qs.deleted()

返回所有 deleted=True 的通知,同时过滤当前查询集。必须与 SOFT_DELETE=True 一起使用。

qs.active()

返回所有 deleted=False 的通知,同时过滤当前查询集。必须与 DELETE=True 一起使用。

qs.mark_all_as_deleted() | qs.mark_all_as_deleted(recipient)

将查询集中的所有通知(可选地也按 recipient 过滤)标记为 deleted=True。必须与 DELETE=True 一起使用。

qs.mark_all_as_active() | qs.mark_all_as_active(recipient)

将查询集中的所有通知(可选地也按 recipient 过滤)标记为 deleted=False。必须与 SOFT_DELETE=True 一起使用。

模型方法

obj.timesince([datetime])

Django 的 timesince 函数的包装器。

obj.mark_as_read()

将当前对象标记为已读。

模板标签

在实际使用通知标签之前,在模板中添加 {% load notifications\_tags %}

notifications_unread

    {% notifications_unread %}

为用户提供未读通知的数量,对于匿名用户不提供任何内容(一个空字符串)。

建议将计数存储在变量中以便进一步处理,例如

    {% notifications_unread as unread_count %}
    ...
    {% if unread_count %}
        You have <strong>{{ unread_count }}</strong> unread notifications.
    {% endif %}

实时更新器 API

为了确保用户始终拥有最新的通知,django-notifications 包含一个简单的 JavaScript API,用于更新 Django 模板中的特定字段。

可以执行两种可能的 API 调用

  1. api/unread_count/ 返回一个 JavaScript 对象,其中包含 1 个键:unread_count,例如

    {"unread_count":1}
    
  2. api/unread_list/ 返回一个 JavaScript 对象,其中包含 2 个键:unread_countunread_list,例如

    {
     "unread_count":1,
     "unread_list":[--list of json representations of notifications--]
    }
    

    通知表示基于django方法:model_to_dict

    查询字符串参数

    • max - 未读列表的最大长度。
    • mark_as_read - 将列表中的通知标记为已读。

    例如,获取api/unread_list/?max=3&mark_as_read=true返回3条通知并将它们标记为已读(在下一次请求中从列表中删除)。

如何使用

  1. 在实际使用通知标签之前,在模板中添加{% load notifications_tags %}

  2. 在您加载javascript资源的区域,按照以下顺序添加以下标签

    <script src="{% static 'notifications/notify.js' %}" type="text/javascript"></script>
    {% register_notify_callbacks callbacks='fill_notification_list,fill_notification_badge' %}
    

    register_notify_callbacks接受以下参数

    1. badge_class(默认live_notify_badge)- 用于显示未读计数并将定期更新的元素的标识class
    2. menu_class(默认live_notify_list)- 用于插入未读项目列表并将定期更新的元素的标识class
    3. refresh_period(默认15)- 从服务器获取未读项的频率(以秒为单位的整数)。
    4. fetch(默认5)- 每次获取的通知数量。
    5. callbacks(默认<empty string>)- 要在每个周期调用的javascript函数的逗号分隔列表。
    6. api_name(默认list)- 要调用的API的名称(可以是listcount)。
    7. mark_as_read(默认False)- 当获取时将通知标记为已读。
  3. 要插入一个实时更新的未读计数,请使用以下模板

    {% live_notify_badge %}
    

    live_notify_badge接受以下参数

    • badge_class(默认live_notify_badge)- 创建用于显示未读计数的<span>元素的标识class
  4. 要插入一个实时更新的未读列表,请使用以下模板

    {% live_notify_list %}
    

    live_notify_list接受以下参数

    • list_class(默认live_notify_list)- 创建用于将通知列表插入的<ul>元素的标识class

使用bootstrap与live-updater结合使用

Live-updater可以通过最小代码集成到bootstrap中。

要创建包含未读计数的实时更新的bootstrap徽章,只需使用模板标签

{% live_notify_badge badge_class="badge" %}

要创建包含最近未读通知选择的实时更新的bootstrap下拉菜单,只需使用模板标签

{% live_notify_list list_class="dropdown-menu" %}

使用javascript回调自定义通知显示

虽然未读计数器实时通知应该适合大多数用例,但用户可能希望更改未读通知的显示方式。

register_notify_callbackscallbacks参数决定了在执行未读API调用时调用哪些javascript函数。

要添加自定义javascript回调,只需将其添加到列表中,如下所示

{% register_notify_callbacks callbacks='fill_notification_badge,my_special_notification_callback' %}

上述操作将导致回调更新未读计数徽章,并调用自定义函数my_special_notification_callback。所有回调函数都按惯例接受一个名为data的单个参数,它包含API的整个结果。

例如,以下函数将获取最近的未读消息列表并将它们记录到控制台

function my_special_notification_callback(data) {
    for (var i=0; i < data.unread_list.length; i++) {
        msg = data.unread_list[i];
        console.log(msg);
    }
}

测试live-updater

  1. 克隆仓库
  2. 运行./manage.py runserver
  3. 浏览到yourserverip/test/
  4. 点击'Make a notification',5-10秒后应在列表中看到一个新通知。

序列化django-notifications模型

见此处 - https://django-rest-framework.django.ac.cn/api-guide/relations/#generic-relationships

在此示例中,目标对象可以是Foo或Bar类型,将使用适当的序列化程序。

class GenericNotificationRelatedField(serializers.RelatedField):

    def to_representation(self, value):
        if isinstance(value, Foo):
            serializer = FooSerializer(value)
        if isinstance(value, Bar):
            serializer = BarSerializer(value)

        return serializer.data


class NotificationSerializer(serializers.Serializer):
    recipient = PublicUserSerializer(User, read_only=True)
    unread = serializers.BooleanField(read_only=True)
    target = GenericNotificationRelatedField(read_only=True)

感谢@DaWy

AbstractNotification模型

如果您需要自定义通知模型以添加字段或依赖于应用程序的定制功能,可以继承并扩展AbstractNotification模型,示例

#In your_app/models.py

from django.db import models
from notifications.base.models import AbstractNotification


class Notification(AbstractNotification):
    # custom field example
    category = models.ForeignKey('myapp.Category',
                                 on_delete=models.CASCADE)

    class Meta(AbstractNotification.Meta):
        abstract = False

您需要在setting.py中定义NOTIFICATIONS_NOTIFICATION_MODEL设置,如下所示

# In your_project/settings.py

NOTIFICATIONS_NOTIFICATION_MODEL = 'your_app.Notification'

备注

电子邮件通知

将电子邮件发送给用户的功能尚未集成到这个库中。因此,如果您需要此功能,请自行实现。为此,已预留字段 Notification.emailed 以简化操作。

示例应用程序

notifications/tests/sample_notifications 中实现了一个示例应用程序,该应用程序扩展了 django-notifications 以测试其可扩展性。您可以通过以下方式设置环境变量 SAMPLE_APP 来运行示例应用程序

export SAMPLE_APP=1
# Run the Django development server with sample_notifications app installed
python manage.py runserver
# Unset SAMPLE_APP to remove sample_notifications app from list of INSTALLED_APPS
unset SAMPLE_APP

django-notifications 团队

核心贡献者(按字母顺序排列)

贡献

我们正在寻找贡献者,如果您愿意为此项目投入时间和精力,请联系 杨宇博

项目详情


下载文件

根据您的平台下载文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分发

django-notifications-hq-1.8.3.tar.gz (32.2 kB 查看哈希值)

上传时间

由以下组织支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面