新的聊天消息通知 Django 频道

我已经Django Channels 2.1.2按照教程在我的 Django 应用程序中进行了设置,现在需要为新消息设置通知系统。我想以最简单的方式做到这一点。

我可以通过浏览器推送通知来做到这一点,但我不想那样做。我希望它像 Stack Overflow 一样,其中有一个红色数字代表新消息的实例。

这里的一个答案说

对于通知,您只需要两个模型:UserNotification。在连接时将范围设置为当前经过身份验证的用户。post_save在您的Notification模型上设置 信号以触发消费者方法向通知对象的用户发送消息。——

我正在努力思考这会是什么样子,我已经有了一个User模型但没有Notification一个。

聊天仅在 2 个用户之间进行,它不是聊天室,而是更多的聊天线程。2个html模板是inbox.htmlthread.html


明月笑刀无情
浏览 195回答 2
2回答

绝地无双

实现通知系统的一种简单方法可以是:当你想显示一条新消息时,一旦你在 websocket 上收到消息,就使用 JS 操作 HTML。每当与元素进行交互时,这意味着用户已阅读通知,使用 websocket 将消息发送回服务器。您Notification可以拥有ForeignKeys用户和消息以及BooleanField阅读状态。每当您向用户发送消息时,都应该在消息中附加 notification_id,#consumer.pyasync 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.htmlsocket.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));});您可以根据需要将单个/所有未读通知标记为已读。

RISEBY

我无法将其标记为重复,因为它有赏金。但解决方案是,您需要两个以上的模型。根据这篇文章,你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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python