【问题标题】:Django templating language syntax for navbar notifications用于导航栏通知的 Django 模板语言语法
【发布时间】:2019-09-10 10:38:55
【问题描述】:

我正在尝试在我的Django Channels 2.1.2 项目中使用 Django 模板语言在 Facebook 样式的通知弹出窗口中呈现任何未读的聊天消息。

未读的chatmessages 列表(在它们各自的threads 中)没有显示,因为我在使用正确的语法时遇到了问题。

这就是前端的样子。当您单击消息图标时,通知会消失。

我有一个Notification 模型

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)

    def __str__(self):
        return f'{self.id}'

navbar.html

 {% if user.is_authenticated %}
  <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">{{ notifications.notification_chat }}</span>
      {% endfor %}
      <div id="notificationContainer">
            <div id="notificationTitle">Notifications</div>
            <div id="notificationsBody" class="notifications">
            {{ notification.notification_chatessage?? }}
            </div>
            <div id="notificationFooter"><a href="{% url 'chat:inbox' %}">See All</a></div>
      </div>
  </li>

base.html

  <script>
    $(document).ready(function() {
      $("#notificationLink").click(function() {
        $("#notificationContainer").fadeToggle(300);
        $("#notification_id").fadeOut("slow");
        return false;
      });

      //Document Click hiding the popup
      $(document).click(function() {
        $("#notificationContainer").hide();
      });

      //Popup on click
      $("#notificationContainer").click(function() {
        return false;
      });
    });
  </script>

context_processors.py

def notification(request):
    if request.user.is_authenticated:
        notification = Notification.objects.filter(notification_user=request.user)
        return {'notification':notification}
    return Notification.objects.none()

我在设置中也添加了上下文处理器 在正确的地方。 notification_id 应该使用消息 WebSocket 发送,并在每次发送新消息时更新(我仍然没有成功地做到这一点)。

consumers.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

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

除了帮助我解决这个问题之外,我非常感谢任何好的学习资源。

【问题讨论】:

  • @BearBrown 希望你能看到我在做什么!
  • 我没有看到您向导航栏添加新通知的代码

标签: python django django-models django-templates django-views


【解决方案1】:

要引用通知消息,您应该使用{{notifications.notification_chat.message}}。此外,为了显示所有通知,您必须遍历所有通知。

navbar.html

{% if user.is_authenticated %}
              <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="inbox-{{notifications.id}}">{{ notifications.notification_chat.message }}</span>

                  {% endfor %}
                  <div id="notificationContainer">
                        <div id="notificationTitle">Notifications</div>
                        <div id="notificationsBody" class="notifications">
                        {% for notifications in notification %}

                            <span id="notification-{{notifications.id}}">{{ notifications.notification_chat.message }}</span>

                        {% endfor %}
                        </div>
                        <div id="notificationFooter"><a href="{% url 'chat:inbox' %}">See All</a></div>
                  </div>
              </li>

我还注意到,在您的thread.html 中,当您收到服务器的响应时,您并没有更新通知。您可以使用 id 来发送prepend 新通知。

【讨论】:

  • 非常感谢。该消息现在显示在弹出窗口中,但是您是对的,当我从服务器收到响应时,我没有更新通知,因此导航栏没有显示正确的数据。我仍然不清楚如何prepend 使用 django 频道 websockets。您在回答我之前的问题时暗示要向thread.html 添加一些js,但我已经把它放在那里并且什么也没发生。
  • 所以$(#notification-element).on("click", function() { data = {"type":"notification_read", "username": username, "notification_id": notification_id}; etc 进入thread.html 并在发送消息时将该数据发送到Notification 模型?默认是unread?那么在base.html页面上,当用户点击弹出窗口时,js脚本需要将notification_id更改为read
  • 第一个评论:找到评论// Find the notification icon/button/whatever,然后在其下方,使用$("#notificationContainer").prepend("&lt;span id=...")$("#notificationLink").append("&lt;span id=...")之类的东西
  • 第二条评论:js 无法更新您的模型。当您将数据发送到websocket_receive 时,您需要按照已经建议的方式更新状态。这意味着在应用程序收到与特定通知交互的通道的响应之前,系统会将其视为未读通知。因此,即使用户在没有与通知交互的情况下重新加载页面,他也可以看到有一个新的通知给他
  • 第三条评论:是的,对于每个用户的每个通知(需要向其发送通知),表中都会有一个新条目,以便您可以跟踪哪个用户与哪个通知进行了交互。 (例如团队消息)
猜你喜欢
  • 2019-02-01
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 2012-11-29
相关资源
最近更新 更多