创建Notification实例,并在每次收到Django通道时将其保存到数据库

时间:2019-05-01 11:07:49

标签: python django django-views django-channels

在我的Django Channels 2.1.2聊天应用程序中,我有一个Notification模型,该模型向用户提供未读消息的通知(使用JQuery)。

class Notification(models.Model):
    notification_user = models.ForeignKey(User, on_delete=models.CASCADE)
    notification_chat = models.ForeignKey(ChatMessage, on_delete=models.CASCADE)
    notification_read = models.BooleanField(default=False)

每次通过Websocket收到消息时,我需要保存一个Notification模型的实例(以聊天和用户作为args)。

然后,该实例将用于用未读的通知填充通知中心。用户单击红色图标时,notification_read

中将触发consumers.py方法
async def websocket_receive(self, event):
        # when a message is recieved from the websocket
        print("receive", event)
        message_type = json.loads(event.get('text','{}')).get('type')
        print(message_type)
        if message_type == "notification_read":
            # Update the notification read status flag in Notification model.
            notification_id = '????'
            notification = Notification.objects.get(id=notification_id)
            notification.notification_read = True
            notification.save()  #commit to DB
            print("notification read")
            return

当前这行不通,因为我没有notification_id,因为通知没有保存到数据库中。我不确定每次通过websocket收到消息时如何编写执行此操作的方法。

我的代码在下面。

consumers.py

class ChatConsumer(AsyncConsumer):
    async def websocket_connect(self, event):
        print('connected', event)

        other_user = self.scope['url_route']['kwargs']['username']
        me = self.scope['user']
        #print(other_user, me)
        thread_obj = await self.get_thread(me, other_user)
        self.thread_obj = thread_obj
        chat_room = f"thread_{thread_obj.id}"
        self.chat_room = chat_room
        # below creates the chatroom
        await self.channel_layer.group_add(
            chat_room,
            self.channel_name
        )

        await self.send({
            "type": "websocket.accept"
        })

    async def websocket_receive(self, event):
        # when a message is recieved from the websocket
        print("receive", event)

        message_type = json.loads(event.get('text','{}')).get('type')
        print(message_type)
        if message_type == "notification_read":
            # Update the notification read status flag in Notification model.
            notification_id = 'chat_message'
            notification = Notification.objects.get(id=notification_id)
            notification.notification_read = True
            notification.save()  #commit to DB
            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 = 'notification'
            myResponse = {
                'message': msg,
                'username': username,
                'notification': notification_id,
            }
            await self.create_chat_message(user, msg)

            # broadcasts the message event to be sent, the group send layer
            # triggers the chat_message function for all of the group (chat_room)
            await self.channel_layer.group_send(
                self.chat_room,
                {
                    'type': 'chat_message',
                    'text': json.dumps(myResponse)
                }
            )
    # chat_method is a custom method name that we made
    async def chat_message(self, event):
        # sends the actual message
        await self.send({
                'type': 'websocket.send',
                'text': event['text']
        })

    async def websocket_disconnect(self, event):
        # when the socket disconnects
        print('disconnected', event)

    @database_sync_to_async
    def get_thread(self, user, other_username):
        return Thread.objects.get_or_new(user, other_username)[0]

    @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)

1 个答案:

答案 0 :(得分:1)

已通过在def create_chat_message

下的consumers.py中添加此功能来解决
@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

还要添加

other_user = self.scope['url_route']['kwargs']['username']
other_user = User.objects.get(username=other_user)
await self.create_notification(other_user, msg)

之后

await self.create_chat_message(user, msg)