【发布时间】:2019-09-22 02:35:51
【问题描述】:
我正在使用带有 Django Channels WebSockets 的 JQuery/JS 来配置聊天消息的实时通知。
当用户有任何带有nofication_read=False 的Notification 对象时,它们会使用以下代码在导航栏中呈现出来。
{{ notification|length }} 显示带有nofication_read=False 的Notification 对象的数量。
navbar.html
<li id="notification_li" class="nav-item">
<a class="nav-link" href="#" id="notificationLink">
<span id="notification_id{{notification_id}}">{{ notification|length }}</span>
<div id="notificationContainer">
<div id="notificationTitle">Notifications</div>
<div id="notificationsBody" class="notifications">
{% for notifications in notification|slice:"0:10" %}
<span id="notification-{{notification.id}}">
{{ notifications.notification_chat.message }}
via {{ notifications.notification_chat.user }}
at {{ notifications.notification_chat.timestamp }}
</span>
{% endfor %}
我知道这不是实时的。
但问题是当用户刷新页面并点击红色图标span id=notification_id以显示他们的未读通知列表时,数据通过websocket(JSON.stringify)发送为"type": "notification_read",它调用if message_type == "notification_read": 中的consumers.y 命令在数据库中将它们标记为nofication_read=True。
当用户刷新页面时,红色图标不再存在,当他们尝试点击背景链接时,在浏览器控制台中出现错误,无法点击
Uncaught ReferenceError: notification_id is not defined
一旦他们收到另一个通知并且页面被刷新,它显然会再次变得可点击。
在初始点击之后的任何时候,用户应该仍然可以点击并查看read 通知列表。
consumers.py
class ChatConsumer(AsyncConsumer):
...
async def websocket_receive(self, event):
message_type = json.loads(event.get('text','{}')).get('type')
if message_type == "notification_read":
user = self.scope['user']
username = user.username if user.is_authenticated else 'default'
# Update the notification read status flag in Notification model.
notification = Notification.objects.filter(notification_user=user).update(notification_read=True)
print("notification read")
return
front_text = event.get('text', None)
if front_text is not None:
loaded_dict_data = json.loads(front_text)
msg = loaded_dict_data.get('message')
user = self.scope['user']
username = user.username if user.is_authenticated else 'default'
notification_id = 'default'
myResponse = {
'message': msg,
'username': username,
'notification': notification_id,
}
...
await self.create_chat_message(user, msg)
other_user = self.scope['url_route']['kwargs']['username']
other_user = User.objects.get(username=other_user)
await self.create_notification(other_user, msg)
...
@database_sync_to_async
def create_chat_message(self, me, msg):
thread_obj = self.thread_obj
return ChatMessage.objects.create(thread=thread_obj, user=me, message=msg)
@database_sync_to_async
def create_notification(self, other_user, msg):
last_chat = ChatMessage.objects.latest('id')
created_notification = Notification.objects.create(notification_user=other_user, notification_chat=last_chat)
return created_notification
context_processors.py
def notification(request):
if request.user.is_authenticated:
notification = Notification.objects.filter(notification_user=request.user, notification_read=False)
return {
'notification':notification,
return Notification.objects.none()
base.html
<script>
$(document).ready(function() {
$("#notificationLink").click(function() {
var data = {
"type": "notification_read",
"username": username,
"notification_id": notification_id,
}
socket.send(JSON.stringify(data));
$("#notificationContainer").fadeToggle(300);
$("#notification_id").fadeOut("slow");
return false;
});
...
var incomingMsg = $('.incoming_msg')
socket.onmessage = function(e) {
console.log("message", e)
var chatDataMsg = JSON.parse(e.data)
incomingMsg.append('<li>' + chatDataMsg.message + ' from ' + chatDataMsg.username + '</li>')
}
【问题讨论】:
-
您好,在
"notification_id": notification_id之前,您应该定义notification_id,但在您的情况下,您需要在此处循环示例stackoverflow.com/questions/16191727/… -
username和notification_id定义在哪里,您在点击处理程序内的datavar 中引用? -
@dirkgroten 我已经更新以显示更多我的
consumers.py但是是的,你是对的,它们没有在 base.html 中定义? -
你只是有一个javascript错误,所以python代码在这里并不相关。只是你的模板和javascript。是的,变量
username和notification_id没有在javascript 中定义(不确定username,因为它不会引发错误)。 -
@dirkgroten 抱歉,是的,我忘了我的模板中有
<input type='hidden' id='username' value='{{ user.username }}' />
标签: javascript python jquery django django-views