New message notification django-channels

I know someone has already asked this question in stackoverflow, in fact this is the question: New chat message notification Django Channels, the answer they gave is exactly what I want to do, also my code or project has the same code of the person who ask. The problem is the following, I took a deep look and tried it in many ways, unfortunately, it did not work for me and I did not understand it very well. I would love someone to explain it to me, and teach me either with my modified code or what should I do to adapt the notification system when the user receives a new message, my code is the following:

consumers.py

import asyncio import json  from django.contrib.auth import get_user_model from channels.consumer import AsyncConsumer from channels.db import database_sync_to_async  from .models import Thread, ChatMessage  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         await self.channel_layer.group_add(             chat_room,             self.channel_name         )          await self.send({             "type": "websocket.accept"         })         # await asyncio.sleep(10)      async def websocket_receive(self, event):         # when a message is received from the websocket         print("receive", event)          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,             }              await self.create_chat_message(user, msg)              # broadcast the message event to be send             await self.channel_layer.group_send(                 self.chat_room,                 {                     "type": "chat_message",                     "text": json.dumps(myResponse)                 }             )      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 connects         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) 

models.py

from django.db import models  from django.conf import settings from django.db import models from django.db.models import Q   class ThreadManager(models.Manager):     def by_user(self, user):         qlookup = Q(first=user) | Q(second=user)         qlookup2 = Q(first=user) & Q(second=user)         qs = self.get_queryset().filter(qlookup).exclude(qlookup2).distinct()         return qs      def get_or_new(self, user, other_username): # get_or_create         username = user.username         if username == other_username:             return None         qlookup1 = Q(first__username=username) & Q(second__username=other_username)         qlookup2 = Q(first__username=other_username) & Q(second__username=username)         qs = self.get_queryset().filter(qlookup1 | qlookup2).distinct()         if qs.count() == 1:             return qs.first(), False         elif qs.count() > 1:             return qs.order_by('timestamp').first(), False         else:             Klass = user.__class__             user2 = Klass.objects.get(username=other_username)             if user != user2:                 obj = self.model(                         first=user,                          second=user2                     )                 obj.save()                 return obj, True             return None, False   class Thread(models.Model):     first        = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='chat_thread_first')     second       = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='chat_thread_second')     updated      = models.DateTimeField(auto_now=True)     timestamp    = models.DateTimeField(auto_now_add=True)          objects      = ThreadManager()      @property     def room_group_name(self):         return f'chat_{self.id}'      def broadcast(self, msg=None):         if msg is not None:             broadcast_msg_to_chat(msg, group_name=self.room_group_name, user='admin')             return True         return False   class ChatMessage(models.Model):     thread      = models.ForeignKey(Thread, null=True, blank=True, on_delete=models.SET_NULL)     user        = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='sender', on_delete=models.CASCADE)     message     = models.TextField()     timestamp   = models.DateTimeField(auto_now_add=True) 

thread.html

{% extends "base.html" %}  {% block content %} <h3>Thread for {% if user != object.first %}{{ object.first }}{% else %}{{ object.second }}{% endif %}</h3> <ul id='chat-items'> {% for chat in object.chatmessage_set.all %}  <li>{{ chat.message }} via {{ chat.user }}</li>  {% endfor %} </ul>  <form id='form' method='POST'> {% csrf_token %}     <input type='hidden' id='myUsername' value='{{ user.username }}' /> {{form.as_p }} <input type='submit' class='btn btn-primary'/> </form>  {% endblock %}  {% block script %} <script src='https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.js'> </script> <script> // websocket scripts // console.log(window.location) var loc = window.location var formData = $("#form") var msgInput = $("#id_message") var chatHolder = $("#chat-items") var me = $("#myUsername").val()  var wsStart = 'ws://' if (loc.protocol == 'https:') {     wsStart = 'wss://' } var endpoint = wsStart + loc.host + loc.pathname + '/' var socket = new ReconnectingWebSocket(endpoint)  socket.onmessage = function(e){     console.log("message", e)     var chatDataMsg = JSON.parse(e.data)     chatHolder.append("<li>" + chatDataMsg.message + " via " + chatDataMsg.username + "</li>") }  socket.onopen = function(e){     console.log("open", e)     formData.submit(function(event){         event.preventDefault()         var msgText = msgInput.val()         // chatHolder.append("<li>" + msgText + " via " + me + "</li>")          var finalData = {             'message': msgText         }         socket.send(JSON.stringify(finalData))         formData[0].reset()     }) } socket.onerror = function(e){     console.log("error", e) } socket.onclose = function(e){     console.log("close", e) }  </script> {% endblock %} 

user_home.html

{% load static %} <!DOCTYPE html> <html> <head>     <title>HOME</title>     <link rel='stylesheet' type='text/css' href="{% static 'css/styles.css' %}">     <link rel='stylesheet' type='text/css' href="{% static 'css/navbar.css' %}">     <link rel='stylesheet' type='text/css' href="{% static 'css/parallax.css' %}">     <link rel='stylesheet' type='text/css' href="{% static 'css/footer.css' %}">     <link rel='stylesheet' type='text/css' href="{% static 'css/loginbuttons.css' %}">     <link rel='stylesheet' type='text/css' href="{% static 'css/login2.css' %}"> </head> <body>     <style>       a{text-decoration:none}  body {   font-family: Arial, Helvetica, sans-serif; }  .notification {   background-color: #f6f5f7;   color: white;   text-decoration: none;   padding: 4px 5px;   position: fixed;   top: 70px;   right: 5px;   display: inline-block;   border-radius: 50%; }  .notification:hover {   background: rgb(175, 175, 175); }  .notification .badge {   position: fixed;   top: 64px;   right: 4px;   padding: 0px 5px;   border-radius: 50%;   background-color: red;   color: white; }     </style>    <!-- The pallarax effect of the portada -->   <div id="parallax">       <h1>MI FAMILIA</h1>       <h2>ES UN</h2>       <h3>DESASTRE</h3>   </div>     <!--Login button-->   <a class="button type1" href="/logout">       Logout   </a>   <label style="position: fixed; top: 19px; right: 170px; color: #fff;">             {% csrf_token %}       {{ user.username }}   </label>     <!--The chat button and help-->   <a href="/messages" class="notification">     <img src="https://img.pngio.com/text-message-icon-png-126137-free-icons-library-text-message-icon-png-512_512.jpg"        style="width: 30px; height: 30px; position: relative; top: 4px;">     <span class="badge">1</span>                             <!--This is the span element-->   </a>    <!--the presentation-->   <div class="parallax"></div>    <div style="height:500px;background-color:#737585;font-size:36px; color: rgb(223, 219, 219);">   Scroll Up and Down this page to see the parallax scrolling effect.   This div is just here to enable scrolling.   Tip: Try to remove the background-attachment property to remove the scrolling effect.   </div>    <div class="parallax"></div>     <!--Footer-->   <div id="site-content">     <h6 style="color: aliceblue; position: absolute; right: 300px; top: -80px; font-size: 70px;">Qué estas Esperando?</h6>   </div>   <a href="#">     <button>TERAPIA</button>   </a>     <!-- the navbar define -->   <header>       <input type='checkbox' id='toggle' style='display:none;' />       <label class='toggle-btn toggle-btn__cross' for='toggle'>         <div class="bar"></div>         <div class="bar"></div>         <div class="bar"></div>       </label>       <nav>         <ul>           <li><a href="/home">Inicio</a></li>           <li><a href="#">Ayuda</a></li>           <li><a href="#">Consultores</a></li>           <li><a href="#">Contactanos</a></li>         </ul>       </nav>   </header>       <script src="{% static 'js/styles.js' %}"></script>   <script src="{% static 'js/footer.js' %}"></script>     

user_home.html is the home page for the user, thread is the one for the chat room, in user_home.html I comment the span element I want to show when there is a new unread message, the class of the span is "badge", and when they click on the message button that contains the badge the badge desappear. thanks for your help.

Add Comment
0 Answer(s)

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.