嗨,我有典型的 django 应用程序,用于使用 websockets 进行实时通知
有2个应用程序“核心”和“通知”
创建评论时,我需要在通知页面上显示通知。我向已安装的应用程序添加了频道核心和通知
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"channels",
"core",
"notification",
]
添加了asgi配置
ASGI_APPLICATION = "reviewproject.asgi.application"
配置的通道层
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels.layers.InMemoryChannelLayer',
},
}
这里是asgi.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import notification.routing
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "reviewproject.settings")
application = ProtocolTypeRouter(
{
"http": get_asgi_application(),
'websocket': AuthMiddlewareStack(
URLRouter(
notification.routing.websocket_urlpattern
)
)
}
)
我也有routing.py
from django.urls import re_path
from . import consumers
websocket_urlpattern = [
re_path(r'ws/notification/$', consumers.NotificationConsumer.as_asgi()),
]
消费者.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class NotificationConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.group_name = "notification"
await self.channel_layer.group_add(self.group_name, self.channel_name)
await self.accept()
async def disconnect(self):
await self.channel_layer.group_discard(self.group_name, self.channel_name)
async def send_message(self, event):
message = event['message']
await self.send(text_data=json.dumps({'message': message}))
创建评论时发送通知
class ProductView(View):
def send_notification(self, message):
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)("notification", {"type": "send_message", "message": message})
def get(self, request, pk):
reviews = ReviewModel.objects.filter(product=pk)
product = get_object_or_404(ProductModel, pk=pk)
context = {
"reviews": reviews,
"product": product
}
return render(request, "product.html", context)
def post(self, request, pk, *args, **kwargs):
product = get_object_or_404(ProductModel, pk=pk)
name = request.POST.get("name")
rating = request.POST.get("rating")
review = request.POST.get("review")
new_review = ReviewModel.objects.create(
product=product,
name=name,
rating=rating,
review=review
)
new_review.save()
message = {
"product_name": product.product_name,
"rating": rating,
"review": review
}
self.send_notification(message)
return HttpResponse("Thank you!! Your review is submitted successfully")
我还可以查看呈现通知页面
from django.shortcuts import render
from django.views import View
class NotificationView(View):
def get(self, request):
return render(request, "notification/index.html")
这是我的 html 页面来显示通知
<!DOCTYPE html>
<html>
<head>
<title>Feedback Collection System</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://unpkg.com/[email protected]"></script>
</head>
<body class="body">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<p class="navbar-brand" hx-get="{% url 'dashboard-view' %}" hx-target=".body" hx-push-url="{% url 'dashboard-view' %}">Feedback Collection System</a>
</nav>
<div class="container">
<div>
<h2>Notifications</h2>
</div>
<ul id="notification-list">
</ul>
<script src="https://unpkg.com/[email protected]"></script>
<script>
var socket = new WebSocket('ws://' + window.location.host + '/ws/notification/');
socket.onmessage = function (event) {
var data = JSON.parse(event.data);
// Display the notification dynamically on the page
// For example, you could show it in a toast, modal, or notification bar
alert(data.message);
};
</script>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
但是当我尝试呈现通知页面时,我在回溯时遇到错误
Not Found: /ws/notification/
[01/Aug/2023 16:39:46] "GET /ws/notification/ HTTP/1.1" 404 2606
我有同样的问题,我通过使用 daphne 解决了它,只需按照文档进行安装并使用 daphne。我会好好工作的