Can't establish connection between web socket and server

I'm writing a chat app using django channels, redis and daphne. When I try to submit the message and tap on the button I have GET query, but I've written js in my html file and it has to prevent standart behaviour of this form. I don't know why doesn't it establish the connection and just send GET query, what's wrong here? I've checked redis server, It works. I've installed all required modules, I've checked It with gpt, nothing helps. How to make it establish the connection?

consumer.py:

import json

from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async

from django.apps import apps

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.chat_name = self.scope['url_route']['kwargs']['chat_name']
        await self.channel_layer.group_add(self.chat_name, self.channel_name)

        await self.accept()    
    
    @database_sync_to_async
    def save_message(self, text_data):
        Chat = apps.get_model('chat', 'Chat') 
        ChatMessage = apps.get_model('chat', 'ChatMessage')
        User = apps.get_model('auth', 'User')

        chat = Chat.objects.get(chat_name=text_data['chat_name'])
        sender = User.objects.get(username=text_data['sender'])
        ChatMessage.objects.create(
            chat=chat,
            body=text_data['message'],
            sender = sender,
        )
        
    async def receive(self, text_data):
        print('Received from frontend:', text_data)
        data_json = json.loads(text_data)
        await self.save_message(data_json)

        event = {"type": "send_chat_message", "message": data_json}
        
        await self.channel_layer.group_send(self.chat_name, event)

    async def send_chat_message(self, event):
        await self.send(text_data=json.dumps({"message": event["message"]})) 

chat.html:

{% extends "base.html" %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chat</title>
</head>
<body>
    {% block content %}
    <div class="container">
        <h2>Chat with {{ chat.members.all.0 }}</h2>
        <div class="card">
            <div class="card-body" id="message-container" style="height: 300px; overflow-y: scroll;">
                {% for message in chat_messages %}
                    <p><strong>{{ message.sender.username }}</strong>: {{ message.body }}</p>
                {% empty %}
                    <p>There are no meassages yet...</p>
                {% endfor %}
            </div>
        </div>
        <form action="" id="message-form" name='message-form'>
            <input name="message-input" id="message-input"></input>
            <button type="submit">Send</button>
        </form>
    </div>

    {% endblock %}


    <script>
            const chat_name = "{{ chat.chat_name }}"
            const socket = new WebSocket(`ws://127.0.0.1:8000/ws/chat/${chat_name}/`) // creatimg ws connection

            // sending the message to the socket
            const message_form = document.getElementById("message-form")
            message_form.addEventListener(              // Listener for submit button
                "submit", function (event) {
                    event.preventDefault()
                    let sent_message = document.getElementById("message-input").value // get the value of the input of the form
                    socket.send(
                        JSON.stringify({
                            message: sent_message,
                            chat_name: "{{ chat.chat_name }}",
                            sender: "{{ request.user.username }}"

                        })
                    )
                }
            )

            //Getting the message
            const chats_div = document.getElementById("message-container") // search for container where we will paste the message
            function scrollToBottom() {
                chats_div.scrollTop = chats_div.scrollHeight
            } //???

            //Processing of the message from the server 
            socket.addEventListener("message", function(e) {
                const data = JSON.parse(e.data);
                
                let sender = data.message.sender
                let content = data.message.message
                
                let msg_body = document.createElement("div")
                let msg_sender = document.createElement("div")
                
                msg_body.textContent = content
                msg_sender.textContent = sender
            
                let chats_div = document.getElementById("message-container")
                let msg = document.createElement("p")
                msg.innerHTML = `<strong>${msg_sender.textContent}</strong>: ${msg_body.textContent}`;
                
                chats_div.appendChild(msg);
                scrollToBottom()
            })
    </script>

</body>
</html> 

asgi.py:

import os
import django  

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack

from chat.routing import websocket_urlpatterns

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'messanger.settings')
django.setup() 

application = ProtocolTypeRouter({
    "http": get_asgi_application(),  # Обычные HTTP-запросы
    "websocket": AuthMiddlewareStack(URLRouter(websocket_urlpatterns)), 
})

routings.py:

from django.urls import re_path

from .consumers import ChatConsumer

websocket_urlpatterns = [
    re_path(r"ws/chat/(?P<chat_name>\w+)/$", ChatConsumer.as_asgi()),
]

views.py

from django.shortcuts import render

from .models import *

def chat_list(req):
    chats = req.user.chats.all()
    print(chats)
    return render(req, 'chat_list.html', {'chats': chats})

def chat(req, chat_name):
    chat = req.user.chats.get(chat_name=chat_name)
    chat_messages = ChatMessage.objects.filter(chat=chat)
    return render(req, 'chat.html', {'chat_messages': chat_messages, 'chat': chat})

models.py:

from django.db import models
from django.contrib.auth.models import User


class Chat(models.Model):
    chat_name = models.CharField(max_length=50)
    members = models.ManyToManyField(User, related_name='chats')
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.chat_name
    

class ChatMessage(models.Model):
    body = models.TextField()
    chat = models.ForeignKey(Chat, on_delete=models.CASCADE, related_name='chat')
    sender = models.ForeignKey(User, on_delete=models.CASCADE)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"Message by @{self.sender} from the chat '{self.chat.chat_name}'"

I've just solved it. I forgot about script block in html file. It is subsidiary htmll, so we have to put {% block scripts %} here before <script> tag. Also It is required to put {% extends "base.html" %} inside body.

Back to Top