写点什么

一文教你实战构建消息通知系统 Django

  • 2024-04-02
    广东
  • 本文字数:5988 字

    阅读完需:约 20 分钟

一文教你实战构建消息通知系统Django

本文分享自华为云社区《构建实时消息通知系统:Django实战指南》,作者:柠檬味拥抱。


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

1. 安装 Django


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


pip install django
复制代码

2. 创建 Django 项目和应用


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


django-admin startproject notification_systemcd notification_systempython manage.py startapp notifications
复制代码

3. 定义模型


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


from django.db import modelsfrom django.contrib.auth.models import User
class 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 Signal
notification_sent = Signal(providing_args=["user", "message"])
复制代码

5. 编写信号处理器


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


from django.dispatch import receiverfrom .signals import notification_sentfrom .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 Userfrom 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 = True    notification.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 pathfrom notifications.views import notifications_view, mark_as_read
urlpatterns = [ 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 JsonResponse
def mark_as_read(request, notification_id): notification = Notification.objects.get(pk=notification_id) notification.read = True notification.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 pathfrom .views import notifications_view, mark_as_read, unread_count
urlpatterns = [ 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 JsonResponse
def 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 osfrom celery import Celery
os.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_taskfrom .models import Notification
@shared_taskdef 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_notification
send_notification.delay(user_id, '你有一个新消息')
复制代码

总结:


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


  1. 通过定义模型、创建信号、编写信号处理器,实现了通知系统的基本框架。

  2. 集成了前端框架 Bootstrap,并使用 Ajax 技术实现了标记通知为已读的功能,以及实时更新未读通知数量的功能,提升了用户体验。

  3. 添加了通知删除功能,使用户可以更灵活地管理通知。

  4. 引入了异步任务处理技术 Celery,将通知的生成和发送操作转换为异步任务,提高了系统的性能和响应速度。


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


点击关注,第一时间了解华为云新鲜技术~

发布于: 22 小时前阅读数: 18
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
一文教你实战构建消息通知系统Django_Python_华为云开发者联盟_InfoQ写作社区