使用Django实现信号与消息通知系统【第154篇—Django】

👽发现宝藏

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。

使用Django实现信号与消息通知系统

在Web应用程序中,实现消息通知系统是至关重要的,它可以帮助用户及时了解到与其相关的事件或动态。Django提供了信号机制,可以用于实现这样的通知系统。本文将介绍如何使用Django的信号机制来构建一个简单但功能强大的消息通知系统,并提供相应的代码和实例。

1. 安装 Django

首先,确保你已经安装了 Django。你可以通过 pip 安装它:

pip install django

2. 创建 Django 项目和应用

创建一个 Django 项目,并在其中创建一个应用:

django-admin startproject notification_system
cd notification_system
python manage.py startapp notifications

3. 定义模型

notifications/models.py 文件中定义一个模型来存储通知信息:

from django.db import models
from django.contrib.auth.models import Userclass Notification(models.Model):user = models.ForeignKey(User, on_delete=models.CASCADE)message = models.CharField(max_length=255)created_at = models.DateTimeField(auto_now_add=True)read = models.BooleanField(default=False)

4. 创建信号

notifications/signals.py 文件中创建信号,该信号将在需要发送通知时触发:

from django.dispatch import Signalnotification_sent = Signal(providing_args=["user", "message"])

5. 编写信号处理器

notifications/handlers.py 文件中编写信号处理器,处理信号并创建相应的通知:

from django.dispatch import receiver
from .signals import notification_sent
from .models import Notification@receiver(notification_sent)
def create_notification(sender, **kwargs):user = kwargs['user']message = kwargs['message']Notification.objects.create(user=user, message=message)

6. 发送通知

在你的应用程序中的适当位置,发送信号以触发通知:

from django.contrib.auth.models import User
from notifications.signals import notification_sent# 例如,发送通知给特定用户
user = User.objects.get(username='username')
notification_sent.send(sender=None, user=user, message='你有一个新消息')

7. 显示通知

在你的应用程序中,可以通过查询通知模型来显示用户的通知:

from notifications.models import Notification# 例如,在视图中查询并显示通知
def notifications_view(request):user_notifications = Notification.objects.filter(user=request.user)return render(request, 'notifications.html', {'notifications': user_notifications})

8. 标记通知为已读

当用户查看通知时,你可能需要将它们标记为已读。你可以在视图中执行此操作:

def mark_as_read(request, notification_id):notification = Notification.objects.get(pk=notification_id)notification.read = Truenotification.save()return redirect('notifications_view')

9. 定义通知模板

创建一个 HTML 模板来呈现通知信息。在 templates/notifications.html 文件中定义:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Notifications</title>
</head>
<body><h1>Notifications</h1><ul>{% for notification in notifications %}<li{% if notification.read %} style="color: grey;"{% endif %}>{{ notification.message }}{% if not notification.read %}<a href="{% url 'mark_as_read' notification.id %}">Mark as Read</a>{% endif %}</li>{% endfor %}</ul>
</body>
</html>

10. 配置 URL

配置 URL 来处理通知相关的请求。在 notification_system/urls.py 文件中:

from django.urls import path
from notifications.views import notifications_view, mark_as_readurlpatterns = [path('notifications/', notifications_view, name='notifications_view'),path('notifications/mark_as_read/<int:notification_id>/', mark_as_read, name='mark_as_read'),
]

11. 运行服务器

运行 Django 服务器以查看效果:

python manage.py runserver

现在,你可以访问 http://127.0.0.1:8000/notifications/ 查看通知页面,并且点击“标记为已读”链接来标记通知。

12. 集成前端框架

为了提升通知页面的用户体验,我们可以使用一些流行的前端框架来美化页面并添加一些交互功能。这里以Bootstrap为例。

首先,安装Bootstrap:

pip install django-bootstrap4

settings.py 中配置:

INSTALLED_APPS = [...'bootstrap4',...
]

修改通知模板 notifications.html,引入Bootstrap的样式和JavaScript文件,并使用Bootstrap的组件来美化页面:

{% load bootstrap4 %}<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Notifications</title>{% bootstrap_css %}
</head>
<body><div class="container"><h1 class="mt-5">Notifications</h1><ul class="list-group mt-3">{% for notification in notifications %}<li class="list-group-item{% if notification.read %} list-group-item-light{% endif %}">{{ notification.message }}{% if not notification.read %}<a href="{% url 'mark_as_read' notification.id %}" class="btn btn-sm btn-primary ml-2">Mark as Read</a>{% endif %}</li>{% endfor %}</ul></div>{% bootstrap_javascript %}
</body>
</html>

13. 使用 Ajax 实现标记为已读功能

我们可以使用 Ajax 技术来实现标记通知为已读的功能,这样可以避免刷新整个页面。修改模板文件和视图函数如下:

在模板中,使用 jQuery 来发送 Ajax 请求:

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>$(document).ready(function() {$('.mark-as-read').click(function(e) {e.preventDefault();var url = $(this).attr('href');$.ajax({type: 'GET',url: url,success: function(data) {if (data.success) {window.location.reload();}}});});});
</script>

修改视图函数 mark_as_read

from django.http import JsonResponsedef mark_as_read(request, notification_id):notification = Notification.objects.get(pk=notification_id)notification.read = Truenotification.save()return JsonResponse({'success': True})

14. 添加通知计数功能

为了让用户可以清晰地知道有多少未读通知,我们可以添加一个通知计数的功能,将未读通知的数量显示在页面上。

首先,在 notifications/views.py 中修改 notifications_view 视图函数:

def notifications_view(request):user_notifications = Notification.objects.filter(user=request.user)unread_count = user_notifications.filter(read=False).count()return render(request, 'notifications.html', {'notifications': user_notifications, 'unread_count': unread_count})

然后,在通知模板中显示未读通知的数量:

<div class="container"><h1 class="mt-5">Notifications</h1><div class="alert alert-info mt-3" role="alert">You have {{ unread_count }} unread notification(s).</div><ul class="list-group mt-3">{% for notification in notifications %}<li class="list-group-item{% if notification.read %} list-group-item-light{% endif %}">{{ notification.message }}{% if not notification.read %}<a href="{% url 'mark_as_read' notification.id %}" class="btn btn-sm btn-primary ml-2 mark-as-read">Mark as Read</a>{% endif %}</li>{% endfor %}</ul>
</div>

15. 实时更新通知计数

为了使通知计数实时更新,我们可以使用 Ajax 技术定期请求服务器以获取最新的未读通知数量。

在通知模板中添加 JavaScript 代码:

<script>function updateUnreadCount() {$.ajax({type: 'GET',url: '{% url "unread_count" %}',success: function(data) {$('#unread-count').text(data.unread_count);}});}$(document).ready(function() {setInterval(updateUnreadCount, 5000); // 每5秒更新一次});
</script>

notifications/urls.py 中添加一个新的 URL 路由来处理未读通知数量的请求:

from django.urls import path
from .views import notifications_view, mark_as_read, unread_counturlpatterns = [path('notifications/', notifications_view, name='notifications_view'),path('notifications/mark_as_read/<int:notification_id>/', mark_as_read, name='mark_as_read'),path('notifications/unread_count/', unread_count, name='unread_count'),
]

最后,在 notifications/views.py 中定义 unread_count 视图函数:

from django.http import JsonResponsedef unread_count(request):user_notifications = Notification.objects.filter(user=request.user, read=False)unread_count = user_notifications.count()return JsonResponse({'unread_count': unread_count})

16. 添加通知删除功能

除了标记通知为已读之外,有时用户还可能希望能够删除一些通知,特别是一些不再需要的通知。因此,我们可以添加一个删除通知的功能。

首先,在模板中为每个通知添加一个删除按钮:

<ul class="list-group mt-3">{% for notification in notifications %}<li class="list-group-item{% if notification.read %} list-group-item-light{% endif %}">{{ notification.message }}<div class="btn-group float-right" role="group" aria-label="Actions">{% if not notification.read %}<a href="{% url 'mark_as_read' notification.id %}" class="btn btn-sm btn-primary mark-as-read">Mark as Read</a>{% endif %}<a href="{% url 'delete_notification' notification.id %}" class="btn btn-sm btn-danger delete-notification">Delete</a></div></li>{% endfor %}
</ul>

然后,在 notifications/urls.py 中添加一个新的 URL 路由来处理删除通知的请求:

urlpatterns = [...path('notifications/delete/<int:notification_id>/', delete_notification, name='delete_notification'),
]

接着,在 notifications/views.py 中定义 delete_notification 视图函数:

def delete_notification(request, notification_id):notification = Notification.objects.get(pk=notification_id)notification.delete()return redirect('notifications_view')

最后,为了使用户可以通过 Ajax 删除通知,我们可以修改模板中的 JavaScript 代码:

<script>$(document).ready(function() {$('.delete-notification').click(function(e) {e.preventDefault();var url = $(this).attr('href');$.ajax({type: 'GET',url: url,success: function(data) {if (data.success) {window.location.reload();}}});});});
</script>

17. 添加异步任务处理

在实际应用中,通知系统可能需要处理大量的通知,而生成和发送通知可能是一个耗时的操作。为了避免阻塞用户请求,我们可以使用异步任务处理来处理通知的生成和发送。

17.1 安装 Celery

首先,安装 Celery 和 Redis 作为消息代理:

pip install celery redis
17.2 配置 Celery

在 Django 项目的根目录下创建一个名为 celery.py 的文件,并添加以下内容:

import os
from celery import Celeryos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'notification_system.settings')app = Celery('notification_system')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

settings.py 中添加 Celery 配置:

CELERY_BROKER_URL = 'redis://localhost:6379/0'
17.3 创建异步任务

notifications/tasks.py 中定义异步任务来处理通知的生成和发送:

from celery import shared_task
from .models import Notification@shared_task
def send_notification(user_id, message):user = User.objects.get(pk=user_id)Notification.objects.create(user=user, message=message)
17.4 触发异步任务

在你的应用程序中,当需要发送通知时,使用 Celery 的 delay() 方法触发异步任务:

from notifications.tasks import send_notificationsend_notification.delay(user_id, '你有一个新消息')

总结:

本文介绍了如何使用 Django 构建一个功能强大的消息通知系统,其中涵盖了以下主要内容:

  1. 通过定义模型、创建信号、编写信号处理器,实现了通知系统的基本框架。
  2. 集成了前端框架 Bootstrap,并使用 Ajax 技术实现了标记通知为已读的功能,以及实时更新未读通知数量的功能,提升了用户体验。
  3. 添加了通知删除功能,使用户可以更灵活地管理通知。
  4. 引入了异步任务处理技术 Celery,将通知的生成和发送操作转换为异步任务,提高了系统的性能和响应速度。

通过这些步骤,我们建立了一个功能完善的消息通知系统,用户可以及时了解到与其相关的重要信息,并且可以自由地管理和处理通知,从而增强了应用的交互性、可用性和性能。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/285219.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java学习笔记 | Java基础语法 | 03 | 流程控制语句

文章目录 0 前言1.流程控制语句1.1 流程控制语句分类1.2 顺序结构 2.判断语句2.1 if语句1. if语句格式1练习1&#xff1a;老丈人选女婿练习2&#xff1a;考试奖励 2. if语句格式2练习1&#xff1a;吃饭练习2&#xff1a;影院选座 3. if语句格式3练习1&#xff1a;考试奖励 2.2 …

Maven高级(工程分模块开发,聚合于继承,版本锁定,Mavne私服的搭建和发布)【详解】

目录 一、Maven复习 1. Maven基本概念 1 Maven的作用 2 Maven的仓库 3 坐标的概念 2. Maven安装配置 3. Maven构建项目 4. Maven依赖管理 5. Maven依赖传递 二、工程分模块开发 1. 分模块开发介绍 2. 工程分模块示例 (1) 创建父工程 (2) 创建pojo模块步骤 (3) 创…

【Redis】优惠券秒杀

全局唯一ID 全局唯一ID生成策略&#xff1a; UUIDRedis自增snowflake算法数据库自增 Redis自增ID策略&#xff1a;每天一个key&#xff0c;方便统计订单量ID构造是 时间戳 计数器 Component public class RedisIdWorker {// 2024的第一时刻private static final long BEGIN…

【Linux】vim配置及安装方法

注 安装方法在文章最后 配置文件的位置 在目录 /etc/ 下面&#xff0c;有个名为vimrc的文件&#xff0c;这是系统中公共的vim配置文件&#xff0c;对所有用户都有效。而在每个用户的主目录下&#xff0c;都可以自己建立私有的配置文件&#xff0c;命名为“.vimrc”。例如&…

20240319-图论

图论练习题目 拓扑排序深度优先搜索方法广度优先搜索方法 无向无权图无向有权图有向无权图 利用广度优先搜索算法有向有权图 带排序的广度优先算法/dijkstra最小生成树prims算法Kruskals Algorithm 最小割 min-cut二分图 Bipartite Graph 队列例题1 所有可能的路径例题2 岛屿数…

【Linux】写个日志和再谈线程池

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;信号量和线程池 目录 &#x1f449;&#x1f3fb;日志代码Log.cppMain.cc &#x1f449;&#x1f3fb;线程池代码LockGuard.hpp(自定义互斥锁&#xff0c;进…

Java获取方法参数名称方案||SpringBoot配置顺序注解

一: Java获取方法参数名称的方法 普盲: getDeclaredMethods与getMethods的的区别 1、getMethods返回一个包含某些 Method 对象的数组&#xff0c;这些对象反映此 Class 对象所表示的类或接口的公共 member 方法。 2、getDeclaredMethods返回 Method 对象的一个数组&#xff0c…

python绘图matplotlib——使用记录2

本博文来自于网络收集&#xff0c;如有侵权请联系删除 三维图绘制 1 三维散点图2 三维柱状图三维曲面 1 三维散点图 import matplotlib.pyplot as plt import numpy as npfrom mpl_toolkits.mplot3d import Axes3Dfig plt.figure() # ax fig.gca(projection"3d")…

Docker(二):Docker常用命令

docker 查看docker支持的所有命令和参数。 ➜ ~ docker Management Commands:config Manage Docker configscontainer Manage containersimage Manage imagesnetwork Manage networksnode Manage Swarm nodesplugin Manage pluginssecret …

操作系统究竟是什么?在计算机体系中扮演什么角色?

操作系统究竟是什么&#xff1f;在计算机体系中扮演什么角色&#xff1f; 一、操作系统概念二、操作系统如何管理软硬件资源2.1 何为管理者2.2 操作系统如何管理硬件 三、系统调用接口作用四、用户操作接口五、广义操作系统和狭义操作系统 一、操作系统概念 下面是来自百度百科…

51单片机学习笔记——LED闪烁和流水灯

任务分析 首先要知道LED闪烁主要是怎么工作的&#xff0c;闪烁亮灭自然是一下为高一下为低&#xff0c;亮灭的频率则需要延时来进行控制。 上节已经知道了如何点亮那延时如何做呢首先先编写主框架 这样是否可以通过循环将LED灯一直循环闪烁。 以为while一直在循环所以其实是可…

【评分标准】【网络系统管理】2019年全国职业技能大赛高职组计算机网络应用赛项H卷 无线网络勘测设计

第一部分&#xff1a;无线网络勘测设计评分标准 序号评分项评分细项评分点说明评分方式分值1点位设计图AP编号AP编号符合“AP型号位置编号”完全匹配5AP型号独立办公室、小型会议室选用WALL AP110完全匹配5员工寝室选用智分&#xff0c;其他用放装完全匹配5其它区域选用放装AP…

设计模式(十二):中介者模式(行为型模式)

Mediator&#xff0c;中介者模式&#xff1a;用一个中介对象封装一些列的对象交互。属于行为型模式 Facade&#xff0c;外观模式&#xff1a;为子系统中的一组接口提供一致的界面&#xff0c;facade 提供了一高层接口&#xff0c;这个接口使得子系统更容易使用。属于结构型模式…

Linux升级GCC

文章目录 一、安装 EPEL 仓库二、更新yum三、安装 CentOS 开发工具组四、安装scl五、安装gcc 11六、启用gcc 11七、设置永久使用 一、安装 EPEL 仓库 命令&#xff1a; yum install epel-release -y二、更新yum 命令&#xff1a; yum update -y三、安装 CentOS 开发工具组 …

opencv各个模块介绍(2)

Features2D 模块&#xff1a;特征检测和描述子计算模块&#xff0c;包括SIFT、SURF等算法。 Features2D 模块提供了许多用于特征检测和描述子匹配的函数和类&#xff0c;这些函数和类可用于图像特征的提取、匹配和跟踪。 FeatureDetector&#xff1a;特征检测器的基类&#xf…

[BT]BUUCTF刷题第6天(3.24)

第6天 Web [极客大挑战 2019]PHP Payload&#xff1a; O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";s:3:"100";}这道题考点是网站源码备份文件泄露和PHP反序列化&#xff0c;有篇介…

t-rex2开放集目标检测

论文链接&#xff1a;http://arxiv.org/abs/2403.14610v1 项目链接&#xff1a;https://github.com/IDEA-Research/T-Rex 这篇文章的工作是基于t-rex1的工作继续做的&#xff0c;核心亮点&#xff1a; 是支持图片/文本两种模态的prompt进行输入&#xff0c;甚至进一步利用两…

013_Linux(上传rz,下载sz,tar,zip,unzip)

目录 一、上传、下载 1、通过鼠标操作 &#xff08;1&#xff09;下载 &#xff08;2&#xff09;上传 2、通过命令操作 rz、sz &#xff08;1&#xff09;下载 sz &#xff08;2&#xff09;上传 rz 二、压缩、解压 1、tar命令 &#xff08;1&#xff09;压缩 &…

使用amd架构的计算机部署其他架构的虚拟机(如:arm)

1 下载quem模拟器 https://qemu.weilnetz.de/w64/2 QEMU UEFI固件文件下载(引导文件) 推荐使用&#xff1a;https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd3 QEMU 安装 安装完成之后&#xff0c;需要将安装目录添加到环境变…

vscode的一些技巧

技巧1&#xff1a;调试时传参数 在launch.json的configuration中"pwd"或者"program"选项之后添加如下选项&#xff1a; “--args”:["参数1", "参数2", ..., "参数3] 参数之间使用逗号隔开 技巧2&#xff1a;断点 普通断点使…