2 回答
TA贡献1946条经验 获得超4个赞
实现通知系统的一种简单方法可以是:
当你想显示一条新消息时,一旦你在 websocket 上收到消息,就使用 JS 操作 HTML。每当与元素进行交互时,这意味着用户已阅读通知,使用 websocket 将消息发送回服务器。
您Notification可以拥有ForeignKeys用户和消息以及BooleanField阅读状态。每当您向用户发送消息时,都应该在消息中附加 notification_id,
#consumer.py
async def websocket_receive(self, event):
# when a message is received from the websocket
print("receive", event)
message_type = event.get('type', None) #check message type, act accordingly
if message_type == "notification_read":
# Update the notification read status flag in Notification model.
notification = Notification.object.get(id=notification_id)
notification.notification_read = True
notification.save() #commit to DB
print("notification read")
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 = 'default'
if user.is_authenticated:
username = user.username
myResponse = {
'message': msg,
'username': username,
'notification': notification_id # send a unique identifier for the notification
}
...
在客户端,
// thread.html
socket.onmessage = function(e) {
var data = JSON.parse(event.data);
// Find the notification icon/button/whatever and show a red dot, add the notification_id to element as id or data attribute.
}
...
$(#notification-element).on("click", function(){
data = {"type":"notification_read", "username": username, "notification_id": notification_id};
socket.send(JSON.stringify(data));
});
您可以根据需要将单个/所有未读通知标记为已读。
TA贡献1856条经验 获得超5个赞
我无法将其标记为重复,因为它有赏金。但解决方案是,您需要两个以上的模型。根据这篇文章,你models.py应该看起来像这样:
class MessageThread(models.Model):
title = models.CharField()
clients = models.ManyToManyField(User, blank=True)
class Message(models.Model):
date = models.DateField()
text = models.CharField()
thread = models.ForeignKey('messaging.MessageThread', on_delete=models.CASCADE)
sender = models.ForeignKey(User, on_delete=models.SET_NULL)
你consumers.py应该是这样的:
class ChatConsumer(WebSocketConsumer):
def connect(self):
if self.scope['user'].is_authenticated:
self.accept()
# add connection to existing groups
for thread in MessageThread.objects.filter(clients=self.scope['user']).values('id'):
async_to_sync(self.channel_layer.group_add)(thread.id, self.channel_name)
# store client channel name in the user session
self.scope['session']['channel_name'] = self.channel_name
self.scope['session'].save()
def disconnect(self, close_code):
# remove channel name from session
if self.scope['user'].is_authenticated:
if 'channel_name' in self.scope['session']:
del self.scope['session']['channel_name']
self.scope['session'].save()
async_to_sync(self.channel_layer.group_discard)(self.scope['user'].id, self.channel_name)
添加回答
举报