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

news/2024/5/13 22:37:21

👽发现宝藏

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

使用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.mrgr.cn/p/51727167

相关文章

vivo 消息中间件测试环境项目多版本实践

作者&#xff1a;vivo 互联网中间件团队 - Liu Tao 在开源 RocketMQ 基础之上&#xff0c;关于【测试环境项目多版本隔离】业务诉求的落地与实践。 一、背景 在2022年8月份 vivo 互联网中间件团队完成了互联网在线业务的MQ引擎升级&#xff0c;从RabbitMQ 到 RocketMQ 的平滑…

AI-TestOps --AI自动化测试工具

1.测试行业趋势 随着数字化转型浪潮的汹涌推进,软件测试行业在2024年迎来了革命性的进步。软件测试不仅是软件开发生命周期中的重要环节,更是创新速度和竞争力的关键因素。传统的软件测试正经历着翻天覆地的变化。自动化测试工具的普及、云测试平台的兴起、AI与机器学习技术的应…

etcd与redis之间的区别

一、简介 我们之前用了redis,那么好用为什么还要来用etcd呢,这里就来和大家聊聊为什么有的业务场景选择etcd。 分析:在当今的分布式系统中,数据存储及一致性相当重要。etcd和redis都是我们最受欢迎的开源分布式数据存储的解决方案,但是他们有着不同的试用场景。下面我个人对…

数字化运营策略大揭秘:畅销书《数字化运营》详解

简介 数字化转型已经成为大势所趋&#xff0c;各行各业正朝着数字化方向转型&#xff0c;利用数字化转型方法论和前沿科学技术实现降本、提质、增效&#xff0c;从而提升竞争力。 数字化转型是一项长期工作&#xff0c;包含的要素非常丰富&#xff0c;如数字化转型顶层设计、…

getshell2

怎么进后端 常见CMSgetshell 良精CMS GETSHELL1讲了很多自己看 动易CMS 学校政府 小企业很多这个CMS 网页直接插马 这是秒的方法 图片上传 编辑器漏洞这个CMS也有 怎么找编辑器F12 ctrlf editor 找到编辑器路径 利用文件目录解析漏洞将备份目录名后加上/a.asp然后备份b…

政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(五)—— Dropout和批归一化

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; Dropout和批归一化是深度学习领域中常用的正则化技术…

【小爱同学】小爱同学误将小米汽车识别为“保时捷”:乌龙事件引发网友热议

近日&#xff0c;一个有趣的乌龙事件在社交媒体上引起了广泛关注。有网友在使用小米的人工智能助手小爱同学时&#xff0c;发现了一个令人啼笑皆非的现象&#xff1a;当小爱同学识别小米自家SUV车型——小米SU7的图片时&#xff0c;竟然将其误认为是“保时捷”。这一乌龙识别结…

抗噪/防干扰LCD显示液晶段码屏驱动VK2C23A/B适用于车载胎压仪表,三相电表,工业仪表,民生消费品及小家电应用

随着社会科技的飞速发展,人们越来越频繁地面对各式各样的显示装置,电子技术领域不可避免地面临着便携式信息设备的低成本,低功耗,轻薄等概念课题,市场上越来越趋向于液晶显示屏(LCD)的高清晰度,高分辨率,低功耗,抗干扰等,使得其应用前景非常广阔。VK2C23A/B LQFP64/48…

ESD原理以及射频防护设计

1、ESD概念 ESD(Electro-Static discharge )是广泛存在于你我身边的自然现象,小时候上自然课就学过摩擦生电。而静电对于工业界来说有时候是很头疼的东西,世界上最大的飞艇兴登堡号就是因为静电原因坠毁的。随着IC的规模越来越大,线宽越来越小,芯片也越来越娇贵,EOS(El…

【Mysql】使用mysql语句查看数据库表所占容量空间大小

转载自: https://www.jb51.net/database/294882rgk.htm一、查看所有数据库容量大小1 2 3 4 5 6 7 8 9 10 11 12 13 14SELECTtable_schema AS 数据库,sum( table_rows ) AS 记录数,sum(TRUNCATE ( data_length / 1024 / 1024, 2 )) AS 数据容量(MB),sum(TRUNCATE ( index_lengt…

LVS负载均衡-DR模式配置

LVS&#xff1a;Linux virtual server ,即Linux虚拟服务器 LVS自身是一个负载均衡器&#xff08;Director&#xff09;&#xff0c;不直接处理请求&#xff0c;而是将请求转发至位于它后端的真实服务器real server上。 LVS是四层&#xff08;传输层 tcp/udp&#xff09;负载均衡…

yolov8 pose keypoint解读

yolov8进行关键点检测的代码如下&#xff1a; from ultralytics import YOLO# Load a model model YOLO(yolov8n.pt) # pretrained YOLOv8n model# Run batched inference on a list of images results model([im1.jpg, im2.jpg]) # return a list of Results objects# Pr…

基于HSV色度空间的图像深度信息提取算法FPGA实现,包含testbench和MATLAB辅助验证程序

1.算法运行效果图预览 将FPGA结果导入到matlab显示结果如下:matlab的对比测试结果如下:2.算法运行软件版本 vivado2019.2matlab2022a3.算法理论概述在HSV(Hue, Saturation, Value)色彩模型中,颜色由色调(H)、饱和度(S)和明度(V)三个参数表示。对于深度信息提取而言…

【前端学习——js篇】6.事件模型

具体见&#xff1a;https://github.com/febobo/web-interview 6.事件模型 ①事件与事件流 事件(Events) 事件是指页面中发生的交互行为&#xff0c;比如用户点击按钮、键盘输入、鼠标移动等。在js中&#xff0c;可以通过事件来触发相应的操作&#xff0c;例如执行函数、改变…

蓝桥杯刷题之路径之谜

题目来源 路径之谜 不愧是国赛的题目 题意 题目中会给你两个数组&#xff0c;我这里是分别用row和col来表示 每走一步&#xff0c;往左边和上边射一箭&#xff0c;走到终点的时候row数组和col数组中的值必须全部等于0这个注意哈&#xff0c;看题目看了半天&#xff0c;因为…

flask_Restful数据解析参数设置

add_argument 方法参数详解 add_argument方法可以指定这个字段的名字&#xff0c;这个字段的数据类 型等&#xff0c;验证错误提示信息等&#xff0c;具体如下&#xff1a; default&#xff1a;默认值&#xff0c;如果这个参数没有值&#xff0c;那么将使用这个参数 指定的默认…

Login with Username and Password Your login attempt was not successful, try again. Reason: 坏的凭证

在互联网大厂也干过,学了很多技术,后面去了外包公司干了好多年,也没怎么学习了,更没有去研究架构之类的,到最后只剩下增删改查了。接下来花费半年时间努力站在架构角度去设计和开发,力争下半年换个30K的工作,现在行情不好,只能拿到20K,好了废话不说,写博客吧 -------…

[Java、Android面试]_13_map、set和list的区别

本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于时间有限&#xff0c;每天整理一点&#xff0c;后续会陆续分享出来&#xff0c;感兴趣的朋友可关注收…

JS中为什么forEach方法不能终止

forEach是我们在日常工作中经常使用到的方法,但是你有什么尝试使用forEach进行停止或终止等操作呢?今天我就遇到了这个问题,借此来剖析一下。 一、走进forEach之前对于forEach了解的并不多,只知道它可以遍历数组,如果有这么一个操作: 一个数组[0, 1, 2, 3, 4, 5],打印出…

Docker进阶:Docker-compose 实现服务弹性伸缩

Docker进阶&#xff1a;Docker-compose 实现服务弹性伸缩 一、Docker Compose基础概念1.1 Docker Compose简介1.2 Docker Compose文件结构 二、弹性伸缩的原理和实现步骤2.1 弹性伸缩原理2.2 实现步骤 三、技术实践案例3.1 场景描述3.2 配置Docker Compose文件3.3 使用 docker-…