本文分享自华为云社区《构建实时消息告诉体系: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 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 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 = 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 %}{% 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_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 path
from .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 os
from 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_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_notification
send_notification.delay(user_id, '你有一个新消息')
总结:
本文介绍了怎么运用 Django 构建一个功用强大的消息告诉体系,其间涵盖了以下主要内容:
- 经过界说模型、创立信号、编写信号处理器,完成了告诉体系的基本结构。
- 集成了前端结构 Bootstrap,并运用 Ajax 技能完成了符号告诉为已读的功用,以及实时更新未读告诉数量的功用,提升了用户体会。
- 增加了告诉删去功用,运用户能够更灵敏地办理告诉。
- 引入了异步使命处理技能 Celery,将告诉的生成和发送操作转换为异步使命,提高了体系的性能和响应速度。
经过这些步骤,咱们建立了一个功用完善的消息告诉体系,用户能够及时了解到与其相关的重要信息,并且能够自由地办理和处理告诉,从而增强了运用的交互性、可用性和性能。