How to Build Chat App in Django

In this Python tutorial, I will show you how to build chat app in Django using the concept of WebSocket which is used for real-time communication.

I will explain to you What is Websocket?, how it is different from HTTP protocol and why it is used for real-time applications with its working. Then I will tell you how you can implement the WebSocket using the Django Channel in your project.

Additionally, I will show you how you can set up your project for WebSocket, you will do all these things by building a real-time chat application, where one user can send and receive messages from another user.

How to Build Chat App in Django

Before building a chat app, you need to understand some concepts like Django channels, Websocket, Synchronous and Asynchronous.

What is Websocket?

WebSocket is a protocol for bi-directional communication between the client and the server. This type of protocol is used in real-time applications such as chatting applications and game applications.

  • The WebSocket protocol opens a connection between the client and server in which data can be exchanged continuously without any intervention until the connection is lost (or closed by the client or server) and thus it is a stateful protocol.
  • But in the case of HTTP protocol where the client makes a request to the server and the server fulfils the request with the response, then the connection is closed. So HTTP protocol is inefficient for real-time applications and it is stateless.
  • The WebSocket protocol-based URL starts with ‘ws’ or ‘wss’ such as ‘ws://exmple.com/’ or ‘wss://exmple.com’ which is similar to HTTP protocol like ‘http://exmple.com/’ or ‘https://exmple.com’.

Now you know about the Websocket and how it is important in real-time communication. Let’s know about Channels.

What is Channels in Django

In general, the Django applications handle a synchronous request because Django is built on WSGI which is called Web Server Gateway Interface. To handle the asynchronous request there is a concept called channels which is a new Python specification built on ASGI that is called Asynchronous Server Gateway Interface.

  • But what exactly do synchronous and asynchronous mean? From the programming perspective, synchronous means execution of one task at a time but in the case of asynchronous, execution of multiple tasks at a time and each task is independent from each other.
  • So synchronous means executing the operation in a sequential manner and asynchronous means executing the operation in an independent manner where one operation doesn’t wait for the previous operation to finish.

The channel in Django allows communication between different parts of the application in an asynchronous way. Channel in the Django project allows us to implement the protocol Websockets (or other protocols) to achieve long-lasting connections between applications.

  • The channel is built on the ASGI (Asynchronous Server Gateway Interfaces). There is concept scope and events, so the channel and ASGI separate the incoming connection into scope and events.
  • The scope is details about the connection like the origin of the request, IP address of the WebSockets etc.
  • These details remain available for the duration of the connection and during this duration, different kinds of events can be generated through user actions such as the user sending the message, making an HTTP request or sending and receiving data over the WebSocket.

To handle the events, there is another term called consumer in the channel. A consumer consumes the events generated within scope, basically, it handles the events, and the consumer is a piece of code or basic unit of the channel.

  • The consumer is equivalent to the views in Django which handles the incoming request. When a request comes with a specific URL Django looks for the URL pattern and calls the corresponding view.
  • In the case of a Channel, whenever a request comes in, it looks in the routing table, The routing table is the same as you specify the URL pattern containing the view and path in urls.py. So incoming request is mapped to different consumers in the routing table (which is a file routing.py) that handle the request.

So you can combine more than one consumer to build a large application using the routing.

Now you know about channels, WebSockets, synchronous and asynchronous, you will implement this concept while building the chat application.

How to Build Chat App in Django Project Configuration

First, create a virtual environment using the below command.

python -m venv chatenv

Then activate this environment using the below command.

chatenv\Scripts\activate

Install the Django latest version using the below code.

pip install django

Create a new project named ‘chat_project’ using the below command.

django-admin startproject chat_project .
How to Build Chat App in Django Project Configuration.JPG

Then create a new Django app ‘chat_app’ using the below command.

python manage.py startapp chat_app

After creating the Django app ‘chat_app’, open the project in your preferred IDE such as Vs code, or continue with your terminal or command prompt if you feel comfortable.

Now install the Channels by executing the below command in your terminal.

pip install channels channels-redis
Installing Channels How to Build Chat App in Django.jpg

Create a new model ‘Message’ in the models.py file of your Django app ‘chat_app’ by adding the following code.

from django.db import models

class Message(models.Model):
    content = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'{self.timestamp}: {self.content}'
How to Build Chat App in Django Adding Model Message

Register the Model in the admin.py file by adding the below line of code.

from django.contrib import admin
from .models import Message

admin.site.register(Message)
Registring Model How to Build Chat App in Django

The purpose of the Message model is to store the conversation between the users.

How to Build Chat App in Django Creating Views and Templates

Add the following lines of code at the top of your views.py file in your Django app.

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required

First, create view register_view in the views.py file of your Django app by adding the following code.

def register_view(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user = form.save()
            login(request, user)
            return redirect('chat', recipient_username=user.username)
    else:
        form = UserCreationForm()
    return render(request, 'register.html', {'form': form})
Register View How to Build Chat App in Django Creating Views and Templates

Also, create a new folder called templates in the Django app and create a new template file called register.html, then add the following code to that file.

{% extends 'base.html' %}

{% block title %}Register{% endblock %}

{% block content %}
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<div class="min-h-screen flex items-center justify-center bg-blue-100 py-12 px-4 sm:px-6 lg:px-8">
    <div class="max-w-md w-full space-y-8 bg-white p-6 rounded-lg shadow-md">
        <div>
            <h2 class="mt-6 text-center text-2xl font-extrabold text-gray-900">Register</h2>
        </div>
        <form method="post" class="mt-8 space-y-6">
            {% csrf_token %}

            <div class="rounded-md shadow-sm -space-y-px">
                <div>
                    <label for="{{ form.username.id_for_label }}" class="sr-only">Username</label>
                    <input id="{{ form.username.id_for_label }}" type="text" name="{{ form.username.name }}" required
                        class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
                        placeholder="Username">
                </div>
                <div class="mt-4">
                    <label for="{{ form.email.id_for_label }}" class="sr-only">Email</label>
                    <input id="{{ form.email.id_for_label }}" type="email" name="{{ form.email.name }}" required
                        class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
                        placeholder="Email">
                </div>
                <div class="mt-4">
                    <label for="{{ form.password1.id_for_label }}" class="sr-only">Password</label>
                    <input id="{{ form.password1.id_for_label }}" type="password" name="{{ form.password1.name }}"
                        required
                        class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
                        placeholder="Password">
                </div>
                <div class="mt-4">
                    <label for="{{ form.password2.id_for_label }}" class="sr-only">Confirm Password</label>
                    <input id="{{ form.password2.id_for_label }}" type="password" name="{{ form.password2.name }}"
                        required
                        class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
                        placeholder="Confirm Password">
                </div>
            </div>

            <div class="mt-6">
                <button
                    class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
                    type="submit">
                    Register
                </button>
            </div>
        </form>
    </div>
</div>
{% endblock %}
Register Template How to Build Chat App in Django Creating Views and Templates

Then create view login_view in the same file by adding the below code.

def login_view(request):
    if request.method == 'POST':
        form = AuthenticationForm(request, data=request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            user = authenticate(username=username, password=password)
            if user:
                login(request, user)
                return redirect('chat', recipient_username=user.username)
    else:
        form = AuthenticationForm()
    return render(request, 'login.html', {'form': form})
Login View How to Build Chat App in Django Creating Views and Templates

Also, create a template file login.html in the templates folder of your Django app and add the following code.

{% extends 'base.html' %}
{% block title %}Login{% endblock %}
{% block content %}
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<div class="min-h-screen flex items-center justify-center bg-blue-100 py-12 px-4 sm:px-6 lg:px-8">
    <div class="max-w-md w-full space-y-8 bg-white p-6 rounded-lg shadow-md">
        <div>
            <h2 class="mt-6 text-center text-2xl font-extrabold text-gray-900">Login</h2>
        </div>
        <form method="post" class="mt-8 space-y-6">
            {% csrf_token %}

            <div class="rounded-md shadow-sm -space-y-px">
                <div>
                    <label for="{{ form.username.id_for_label }}" class="sr-only">Username</label>
                    <input id="{{ form.username.id_for_label }}" type="text" name="{{ form.username.name }}" required
                        class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
                        placeholder="Username">
                </div>
                <div class="mt-4">
                    <label for="{{ form.password.id_for_label }}" class="sr-only">Password</label>
                    <input id="{{ form.password.id_for_label }}" type="password" name="{{ form.password.name }}"
                        required
                        class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
                        placeholder="Password">
                </div>
            </div>

            <div>
                <button
                    class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
                    type="submit">
                    Login
                </button>
            </div>
        </form>
    </div>
</div>
{% endblock %}
Login Template How to Build Chat App in Django Creating Views and Templates

Let’s create a view chat_view in the views.py file of your Django app by adding the following code.

@login_required(login_url='login')
def chat_view(request, recipient_username):
    return render(request, 'chat.html', {'recipient_username': recipient_username})
Chat View How to Build Chat App in Django Creating Views and Templates

Again create a template chat.html in the templates folder of your Django app by adding the following code.

{% extends 'base.html' %}

{% block title %}Real-time Chat{% endblock %}

{% block content %}
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<div class="h-screen bg-gray-100 py-10 px-4 sm:px-6 lg:px-8">
    <div class="chat-container bg-white max-w-xl mx-auto rounded-lg shadow-md overflow-hidden">


        <div class="chat-header bg-blue-600 text-white p-4">
            {{recipient_username}}
        </div>

        <div class="chat-messages h-96 overflow-y-auto p-4" id="chat-box">
        </div>


        <div class="border-t border-gray-200 p-4">
            <input type="text"
                class="chat-input w-full px-4 py-2 rounded-md border focus:ring-indigo-500 focus:border-indigo-500"
                id="chat-input" placeholder="Type your message..." />
        </div>
    </div>
</div>
{% endblock %}
How to Build Chat App in Django Chat Page Template

Define the URL for the views by creating a new file called urls.py in your Django app ‘chat_app’ and add the following line of codes.

from django.urls import path
from . import views

urlpatterns = [
    path('chat/<str:recipient_username>/', views.chat_view, name='chat'),
    path('', views.register_view, name='register'),
    path('login/', views.login_view, name='login'),
    path('logout/', views.logout_view, name='logout'),
]
View URLs How to Build Chat App in Django

Now add the following code to the template ‘chat.html’ with <script> tag.

<script>const chatSocket = new WebSocket('ws://' + window.location.host + '/ws/chat/{{ recipient_username }}/'); </script>
How to Build Chat App in Django Defining WebSocket Connection

In the above picture at line number 27, creating a WebSocket instance to provide bi-direction communication or long-live connection using the new WebSocket() method in javascript and assigning it the constant variable chatSocket.

  • The WebScoket accept a URL that is ‘ws://’ + window.location.host + ‘/ws/chat/{{ recipient_username }}/’, the first part ws:// is a websocket protocol prefix to create a connection over an unencrypted connection.
  • Then the window.location.host is used to get the current hostname and the port from the address bar of the browser. If the current URL is http://127.0.0.1:8000/, then it returns the 127.0.0.1:8000.
  • /ws/chat/{{ recipient_username }}/ is the path to the server where the websocket connection will be created with a specific recipient_username ( or the user on the server).
READ:  Python Django "Module not found" error.

Now create a new file called consumers.py in your Django app and add the following line of code.

import json
from channels.generic.websocket import AsyncWebsocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.sender = self.scope['user'].username
        self.recipient = self.scope['url_route']['kwargs']['username']
        await self.accept()
Defining ChatConsumer Class How to Build Chat App in Django

At line number 1 to 2, import the json and AsyncWebsocketConsumer from the library channels.

Then from line number 4 to 8, first define the class ChatConsumer which inherit the base class AsyncWebSocketConsumer. As from the above discussion, you know that the channels allow the Django project to use the asynchronous protocol such as Websocket, HTTP2 etc.

  • So the base class AsyncWebSocketConsumer allows the Django project to handle the WebSocket. Basically, the class ChatConsumer by inheriting the AsyncWebSocketConsumer will handle the WebSocket connection for the chat functionality.
  • Then line 5 defines the asynchronous method connect(self) by using the keyword async, using the async keyword means the method will use the await keyword.
  • self.sender = self.scope[‘user’].username at line 6 retrieves the username of the currently authenticated user from the scope and assigns it to the sender attribute of the ChatConsumer instance.
  • Remember, we talked about how channel and ASGI divide the incoming connection into scope and events. This is the same scope that contains the current connection, including details about the connected user, headers, session, etc.
  • After this at line number 7, self.recipient = self.scope[‘url_route’][‘kwargs’][‘username’] gets the username from the URL route’s keyword arguments and assigns it to the recipient attribute of the ChatConsumer instance.

Finally, line 8 with code await self.accept() is the asynchronous method of the class AsyncWebSocketConsumer that is called to establish the WebSocket connection. Without this method, a WebSocket connection can not be established.

READ:  Payment Gateway Integration with Django

Let’s define the path on the server by creating a new file called routing.py in your Django app ‘chat_app’ and adding the following line of code.

from django.urls import re_path
from .consumers import ChatConsumer

websocket_urlpatterns = [
        re_path(r'ws/chat/(?P<username>\w+)/$', ChatConsumer.as_asgi()),
    ]
How to Build Chat App in Django Websocket URL Pattern

In the above picture, importing function re_path from the module urls of the Django to define the URL pattern using regular expression and the class ChatConsumer from the current directory of the file conumsers.py.

  • Then define a list named websocket_urlpatterns that accepts the URL patterns for the Websocket routes. Providing the URL using the re_path(r’ws/chat/(?P<username>\w+)/$’, ChatConsumer.as_asgi()).
  • Where ws/chat/ matches the URL starting with “ws/chat/” and (?P<username>\w+) is a named capturing group. It matches one or more word characters that are equivalent to [a-zA-Z0-9_] and captures them under the name “username”. Then allows you to extract the matched username from the URL in your view or consumer.
  • Then the as_asgi() method is a part of Django Channels and is used to create an instance of the consumer in an ASGI-compatible format by calling on the class ChatConsumer.as_asgi().

Now open the file asgi.py in your Django project ‘chat_project’ and add the following line of code.

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

from chat_app.routing import websocket_urlpatterns

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chat_project.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    ),
})
ASGI How to Build Chat App in Django

What is the asgi.py file in your Django project? the asgi.py file is the entry point for the asynchronous server or it supports asynchronous features such as Websocket, Server-Sent-Events etc. It is used especially for long-lived connections.

  • The asgi.py file contains the routing logic when the Django channel is used in your project to handle different types of connections such as HTTP, Websocket etc.
  • So for this chat app, you are using the WebSocket connection, and for WebSocket Django channel is required, To work this channel, the required thing is the ASGI server and asgi.py file with configuration to route the WebSocket connection to specific consumers.

In the above code, import the required module or functions from lines 1 to 4, then specify the default Django setting module using DJANGO_SETTINGS_MODULE which is set to chat_project.settings.

  • The purpose of the DJANGO_SETTINGS_MODULE is to tell Django which module to use when Django starts up, especially in the case of ASGI applications.
  • The codes 10 to 17 define the main routing for the application, The ProtocolTypeRouter is the top-level router to decide what to do with the connection based on the protocol. It contains two types of protocol-based connections http and websocket.
  • This line of code “http”: get_asgi_application() handles the HTTP request but in an asynchronous way. Then the traffic related to the WebSocket connection is routed to the “websocket”: AuthMiddlewareStack(), here AuthMiddlewareStack make the user the authenticated user should access the route defined within it using the URLRouter( websocket_urlpatterns).
  • The URLRouter is a router that deals with the WebSocket connection based on the URL pattern defined in the websocket_urlpatterns.

After configuring the asgi.py file, configure the setting.py file by adding the following code.

INSTALLED_APPS = [
    'channels',
    'daphne',
   .....,
    'chat_app',
   
]

ASGI_APPLICATION = 'chat_project.asgi.application'
CHANNEL_LAYERS = {
	"default": {
		"BACKEND": "channels.layers.InMemoryChannelLayer"
	}
}
How to Build Chat App in Django Configuration of Setting

In the above code at line 46, the code ASGI_APPLICATION = ‘chat_project.asgi.application’ denotes the use of the ASGI application while serving the Django project. This code ‘chat_project.asgi.application’ points to the application instance in the asgi.py file of the chat_project.

From lines 48 to 52, define the Django channel using the CHANNEL_LAYERS, where the default channel is InMemoryChannelLayer which is a simple in-memory layer. It’s suitable for local development but is not recommended for production for high-traffic setups.

How to Build Chat App in Django Managing WebSocket Message

To handle WebSocket messages, first, you need to extract the message type by the user in the input field and send it to the consumer through WebSocket connection to handle the messages.

For that, open the template chat.html of the Django app ‘chat_app’ and add the following line of code within <script></script> tag.

document.querySelector('#chat-input').addEventListener('keyup', function (e) {
            if (e.key === 'Enter') {
                const messageInput = document.querySelector('#chat-input');
                const message = messageInput.value;
                chatSocket.send(JSON.stringify({
                    'message': message
                }));
                messageInput.value = '';
            }
        });
Handling Message in Consumer How to Build Chat App in Django Extracting User Input

In the above code at line 29, document.querySelector(‘#chat-inpu) selects the HTML element with an ID equal to #chat-input, this field is the input field where the user types the message.

The event listener ‘keyup’ is added to it using addEventListener(‘keyup’, function (e) {}, this event occurs when a key on the keyboard is released and passed as e. Then the code if (e.key === ‘Enter’) is executed to check that the key that triggered the event ‘keyup’ is the enter key.

If it is the enter key, then the following actions are performed:

  • It selects the input field once more using document.querySelector(‘#chat-input’) and a reference to that element is stored in the messageInput.
  • The input value is extracted using the messageInput.value and stored in the message.
  • After this extracted message is sent to the WebSocket server ‘chatSocket’ using the send() method in JSON format, the message is converted into JSON format using the JSON.stringify({‘message’: message}).
READ:  integrity error in django

This JSON format message is received by the consumer.py file or the consumer through the Websocket connection, Let’s see how to this message is handled.

Now open the consumers.py file of your Django app ‘chat_app’ and add the following line of code to receive and send the data through WebSocket.

import json
from channels.generic.websocket import AsyncWebsocketConsumer

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.sender = self.scope['user'].username
        self.recipient = self.scope['url_route']['kwargs']['username']

        self.room_group_name = "group_chat"
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )
        
        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
    
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message,
                'sender': self.sender
            }
        )

    async def chat_message(self, event):
        message = event['message']
        sender = event['sender']
      
        await self.send(text_data=json.dumps({
            'message': message,
            'sender': sender
        }))
Handling Message in Consumer How to Build Chat App in Django

In the above code from lines 9 to 12, define the group named ‘group_chat’ using self.room_group_name = “group_chat”, this group is a chat room where all the users will be added and receive the message which will be broadcast in the group by each user.

  • In Django, a group is a named collection of channels (users) where you can broadcast messages.
  • Then a method self.channel_layer.group_add() of Django Channel’s channel layer accepts two values the group_name using self.room_group_name and the channel_name that is a unique name to identify the current WebSocket channel using self.channel_name.

At lines 17 to 21, the asynchronous method disconnect() is defined which is called whenever the WebSocket connection is closed, the connection is closed by calling the method self.channel_layer.group_discard(), this method removes the current channel from the group base on the provided group_name and channel_name.

Look at line 23 where an asynchronous method async def receive(self, text_data) with parameter text_data is defined (this is the JSON format data that is sent from your front-end), and the parameter contains the received message from the WebSocket connection.

  • In lines 24 and 25, parsing the JSON data which is the message in the text_data into Python dictionary using the method json.loads() and storing in the variable text_data_json.
  • Then extract the actual message from the text_data_json using text_data_json[‘message’] and store the variable message.
  • After this, broadcasting a message using the asynchronous method await self.channel_layer.group_send() to a specific group that is specified using self.room_group_name with message {‘type’: ‘chat_message’, ‘message’: message, ‘sender’: self.sender}.
  • Where ‘type’:’chat_message’ is a type of message that will be sent, in this case, chat_message which handles this type of message, ‘message’: message is the actual message and the ‘sender’: self.sender which is the information about the user.

Finally, line 36 defines the asynchronous method chat_message(self, event) to handle the message received by the group and extract the message and sender details from the event.

Then it broadcasts the same message to the sender and other members in the group using the method await self.send(). This method chat_message is the same method specified in the above self.channel_layer.group_send() method in the type field as ‘type’: ‘chat_message’.

Again open the template ‘chat.html’ and add the following code within the <script></script> tag.

chatSocket.onmessage = function (e) {
            const data = JSON.parse(e.data);
            const message = data['message'];
            const sender = data['sender'];
            const chatBox = document.getElementById('chat-box');
            const messageElement = document.createElement('div');
            const messageContent = document.createElement('span');

            if (sender === "{{ request.user.username }}") {

                messageElement.classList.add('mb-2', 'flex', 'justify-end');
                messageContent.classList.add('p-3', 'rounded-md', 'bg-indigo-600', 'text-white');
            } else {

                messageElement.classList.add('mb-2', 'flex', 'justify-start');
                messageContent.classList.add('p-3', 'rounded-md', 'bg-gray-300', 'text-gray-900');
            }
       
            messageContent.textContent = `[${sender}]: ${message}`;
            messageElement.appendChild(messageContent);
            chatBox.appendChild(messageElement);
            chatBox.scrollTop = chatBox.scrollHeight;
        };
How to Build Chat App in Django Managing Websocket Message

In the above code at line 29, an event listener ‘onmessage’ is added to the WebSocket object ‘chatSocket’ using chatSocket.onmessage = function (e) {}, this function gets executed whenever a new message (broadcasted message) is received, and the message data becomes available to e.data property.

  • Then from lines 30 to 32, parse the incoming message to an object using the JSON.parse(e.data) and store it in the variable data. After this, using the data, two pieces of information are extracted, the actual message and the sender of that message, then stored in the separate variable message and sender respectively.
  • From lines 33 to 45, based on the message and sender creating a new chat box and styling the chat box based on the user using if (sender === “{{ request.user.username }}”). Then from lines 47 to 50 set the chat box content and give scrolling functionality using chatBox.scrollTop = chatBox.scrollHeight.

Finally, the chat app is ready, let’s run the Django server using the below code and see.

python manage.py runserver

After running the server, open the link http://127.0.0.1:8000/ and you will be redirected to the register page as shown below.

How to Build Chat App in Django Register Page

Again open the same URL in another browser side by side as shown in the below picture and login on both.

How to Build Chat App in Django Login Page

After logging in, you see the chat page as shown in the below picture.

How to Build Chat App in Django Chat Page

Then send a message from one browser for example ‘admin’ as shown in the above picture, and the message will be received on the other browser at the user ‘ks900’, look at the below output.

How to Build Chat App in Django Sending Message

Now send the reply message from the user ‘ks9004’ as shown in the below picture.

Sending Message How to Build Chat App in Django

As you can see you have successfully sent and received the message, well you built the simple chat application using the concept of Websocket in Django. This is how you can implement real-time functionality in your Django project.

Conclusion

In this Python tutorial, you learned how to build a chat app in Django, where you learned the concept of the WebSocket, and Django Channels for real-time communication. You also learned how to establish a WebSocket connection to handle the incoming data and send it back.

You may like to read: