【问题标题】:Notifications unclickable once "read": error "notification_id is not defined"通知一旦“读取”就无法点击:错误“notification_id is not defined”
【发布时间】:2019-09-22 02:35:51
【问题描述】:

我正在使用带有 Django Channels WebSockets 的 JQuery/JS 来配置聊天消息的实时通知。

当用户有任何带有nofication_read=FalseNotification 对象时,它们会使用以下代码在导航栏中呈现出来。

{{ notification|length }} 显示带有nofication_read=FalseNotification 对象的数量。

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/…
  • usernamenotification_id 定义在哪里,您在点击处理程序内的 data var 中引用?
  • @dirkgroten 我已经更新以显示更多我的consumers.py 但是是的,你是对的,它们没有在 base.html 中定义?
  • 你只是有一个javascript错误,所以python代码在这里并不相关。只是你的模板和javascript。是的,变量usernamenotification_id 没有在javascript 中定义(不确定username,因为它不会引发错误)。
  • @dirkgroten 抱歉,是的,我忘了我的模板中有&lt;input type='hidden' id='username' value='{{ user.username }}' /&gt;

标签: javascript python jquery django django-views


【解决方案1】:

"notification_id": notification_id 之前,您应该定义notification_id,但在您的情况下,您需要循环执行,您可以尝试:

 $("#notificationLink").click(function() {

   $('span[id^="notification-"]').each(function(){
        var notification_id = $(this).attr('id').substring(13)
        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 username = '{{ request.user.username }}'

通过您在后端的当前代码,您不需要notification_id,因此您可以简单地删除它:

 $("#notificationLink").click(function() {
    var data = {
      "type": "notification_read",
      "username": username,
    }
    socket.send(JSON.stringify(data));

    $("#notificationContainer").fadeToggle(300);
    $("#notification_id").fadeOut("slow");
    return false;
  });

【讨论】:

  • username 是什么?
  • @BearBrown 嗨,我刚试过这个,我没有收到任何错误,但现在即使有新通知也无法点击通知链接。我的模板中有&lt;input type='hidden' id='username' value='{{ user.username }}' /&gt;,但会用你输入的内容替换它
  • 请检查您的控制台日志,可能是我输入了一些拼写错误或其他代码错误
  • 当我取出$('span[id^="notification-"]').each(function(){ 的线路时,它起作用了!
  • 让我再试一分钟,我想我可能忘记了}
猜你喜欢
  • 2020-12-03
  • 2020-11-07
  • 2022-11-27
  • 2017-06-05
相关资源
最近更新 更多