'how can I receive notification by another user using channels in django?
actually, this is the first time I use channels but it's an easy concept to understand.
I followed a tutorial that took me to the way in which I can send the notification the real-time but there's a part that I can't see at any tutorial where they are oblivious to it.
all tutorials show how can send a notification or messages via chat when I do that for a single user after I open the new page, the page works fine. for example, if I logged in by username "test" and opened a new browser logged in by username "test" will be working fine
the problem is that: when I try to open for example an "incognito page" by google chrome to use a different user such as "new test" username that I want him to receive the notification we can consider him a target user from the sender on the main page "test".
now the data is changing in the database but I can't see that change in front of my eyes unless I reload the web page.
when I tested that out I see javascript doesn't receive any of the data in the "new test" user and I think this problem occurs because of channel_layer somehow.
any help and explanation for what is going on here?
#consumers.py
from channels.consumer import AsyncConsumer
from channels.db import database_sync_to_async
import json
from .models import Notification
from django.contrib.auth.models import User
class NotificationConsumer(AsyncConsumer):
async def websocket_connect(self, event):
await self.send({
'type': 'websocket.accept',
})
user = self.scope['user']
notif_room = f"user_id_{user.id}"
self.notif_room = notif_room
await self.channel_layer.group_add(
notif_room,
self.channel_name
)
async def websocket_receive(self, event):
serialize_data = json.loads(event['text'])
self.comment = serialize_data['comment']
self.user_sender = serialize_data['user_sender']
notif_count = await self.update_notification()
await self.channel_layer.group_send(
self.notif_room,
{
"type": 'send_notif',
'text': json.dumps({'notif_count': notif_count})
}
)
async def send_notif(self, event):
await self.send({
'type': 'websocket.send',
'text': event['text']
})
async def websocket_disconnect(self, event):
print("Disconnect the connections")
@database_sync_to_async
def update_notification(self):
comment = self.comment
user_sender = User.objects.get(id=int(self.user_sender))
notifs = Notification.objects.create(
user_sender=user_sender,
message=comment
)
for users in User.objects.all().exclude(username=self.scope['user'].username):
users.rec.add(notifs)
return Notification.objects.filter(user_receiver=self.scope['user'].id).count()
#file.html
{% extends 'base.html' %}
{% block title %} Data Show {% endblock %}
{% block body %}
<div class="container">
<button type="button" class="btn notification-button btn-primary">
Notifications <span class="badge badge-light">{{ notifications.count }}</span>
</button>
<br><br/>
<form id="formData" method="post">
{% csrf_token %}
{% if user.is_authenticated %}
<input type="text" hidden="hidden" value="{{ user_sender.id }}" name="user">
{% endif %}
<input type="text" name="comment" id="comment">
<input type="submit" value="create" />
</form>
</div>
<script>
let ws_protocol = "ws://";
const navigation = window.location;
let formData = document.getElementById("formData");
let id_name = document.getElementById("id-name");
let user = document.querySelector("input[name='user']");
let comment = document.getElementById("comment");
let notif_label = document.querySelector(".badge");
let notification_button = document.querySelector(".notification-button");
if (navigation.protocol === "https") {
ws_protocol = "wss://";
}
let target = `${ws_protocol}${navigation.host}${navigation.pathname}`
const socket = new WebSocket(target);
socket.onopen = (e) => {
console.log("connection accepted by javascript");
formData.onsubmit = function (e) {
e.preventDefault();
try {
let data = {
"comment": comment.value,
"user_sender": user.value
}
socket.send(JSON.stringify(data))
} catch (e) {
alert("you should login to be able to comment here");
}
}
}
socket.onmessage = (e) => {
console.log("receive message by javascript");
let json_data = JSON.parse(JSON.stringify(e.data))
json_data = JSON.parse(json_data)
notif_label.textContent = json_data.notif_count;
console.log(json_data)
}
socket.onerror = (e) => {
console.log("display error by javascript");
}
socket.onclose = (e) => {
console.log("close connection by javascript");
}
notification_button.onclick = function() {
notif_label.textContent = '';
}
</script>
{% endblock %}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
