Сбой ограничения NOT NULL для каналов Django: chat_chatmessage.message - PullRequest
1 голос
/ 28 апреля 2019

Я пытаюсь завершить работу системы уведомлений в моем приложении Django Channels.

Когда я отправляю сообщение или строку текста через веб-сокет, websocket.recieve генерирует загрузку пустых строк после отправки исходного сообщения.

127.0.0.1:54917 - - [27/Apr/2019:19:04:05] "WSCONNECTING /messages/trilla" - -
connected {'type': 'websocket.connect'}
127.0.0.1:54917 - - [27/Apr/2019:19:04:05] "WSCONNECT /messages/trilla" - -
receive {'type': 'websocket.receive', 'text': '{"message":"hi there"}'}
websocket.receive
receive {'type': 'websocket.receive', 'text': '{"message":""}'}
websocket.receive
receive {'type': 'websocket.receive', 'text': '{"message":""}'}
websocket.receive
receive {'type': 'websocket.receive', 'text': '{"message":""}'}
websocket.receive

Навбар имеет JS-скрипт, который добавляет новые уведомления. HTML-строка создается из сообщения сервера и затем вставляется на страницу HTML.

Я получаю NOT NULL constraint failed: chat_chatmessage.message, когда нажимаю на значок уведомления навигационной панели. Я полагаю, из-за проблемы с пустой строкой, генерирующей загрузку пустых сообщений.

inbox problem

Это журнал, когда я нажимаю на значок уведомления

receive {'type': 'websocket.receive', 'text': '{"type":"notification_read","username":{},"notification_id":{"jQuery33100053785670652706231":{"display":""}}}'}
websocket.receive
2019-04-28 11:59:47,041 ERROR    Exception inside application: NOT NULL constraint failed: chat_chatmessage.message

Ясно, что данные не передаются должным образом. Я следовал руководству по части Django Channels и не имел опыта работы с JS / WebSockets, прежде чем пытаться сделать это, поэтому я ограничен в своих навыках поиска проблемного кода.

consumers.py

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

        message_type = event.get('type', None)  #check message type, act accordingly
        print(message_type)
        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'
            notification_id = 'default'
            if user.is_authenticated:
                username = user.username
            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)

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;
      });
</script>

<script>
    // websocket scripts - client side*
    var loc = window.location
    var formData = $("#form")
    var msgInput = $("#id_message")
    var chatHolder = $('#chat-items')
    var me = $('#myUsername').val()
    var notification = $("#notificationLink")

    var wsStart = 'ws://'
    if (loc.protocol == 'https:') {
      wsStart = 'wss://'
    }
    var endpoint = wsStart + loc.host + loc.pathname
    var socket = new ReconnectingWebSocket(endpoint)

    // below is the message I am receiving
    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.append("<span id=#notification_id>" + notification.notification_id)

      console.log("message", e)
      var chatDataMsg = JSON.parse(e.data)
      chatHolder.append('<li>' + chatDataMsg.message + ' from ' + chatDataMsg.username + '</li>')
    }

    // below is the message I am sending
    socket.onopen = function(e) {
      console.log("open", e)
      formData.submit(function(event) {
        event.preventDefault()
        var msgText = msgInput.val()
        var finalData = {
          'message': msgText
        }
        socket.send(JSON.stringify(finalData))
        formData[0].reset()
      })
    }

Navbar

<li id="notification_li" class="nav-item">
  <a class="nav-link" href="#" id="notificationLink">
    <i class="fas fa-envelope"></i>&nbsp; Inbox</a>
  {% for notifications in notification %}
  <span id="notification_id{{notification_id}}">{{ notifications.notification_chat }}</span>
  {% endfor %}
  <div id="notificationContainer">
    <div id="notificationTitle">Notifications</div>
    <div id="notificationsBody" class="notifications">
      {% for notifications in notification %}
      <a href="{% url 'chat:thread' user %}">
        <span id="notification-{{notification.id}}">
          {{ notifications.notification_chat.message }}
          via {{ notifications.notification_chat.user }}
          at {{ notifications.notification_chat.thread.timestamp }}
        </span>
      </a>
...

Ответы [ 2 ]

0 голосов
/ 29 апреля 2019

когда вы отправляете уведомление о прочтении, вам не нужен весь остальной код, поэтому вы можете просто добавить return

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")
    <b>return</b>
0 голосов
/ 29 апреля 2019

Проблема должна исходить из файла вашей модели. Ограничение NOT NULL установлено для поля, которое вызывает ошибку, когда вы пытаетесь создать его пустым. Таким образом, чтобы преодолеть это, вам нужно установить null=True. Например:

date_of_birth = models.DateField(blank=True, null=True)

Попробуйте взглянуть на модели, используемые в вашей функции create_chat_message.

...