In this tutorial, we will learn how to build a real-time chat application using Django Channels and WebSocket. Django Channels is a powerful extension that allows Django to handle WebSockets, HTTP & HTTP2 protocols.
By the end of this tutorial, you will have a working chat application where users can send and receive messages in real-time. Let’s get started!
Prerequisites
To follow along with this tutorial, you will need the following:
- Python 3.7 or above
- Django 3.2 or above
- Django Channels 3.0 or above
If you don’t have Python installed, you can download it from the official Python website: https://www.python.org/downloads/
To install Django and Django Channels, open a terminal or command prompt and run the following commands:
pip install django
pip install channels
Setting up the Django Project
Let’s start by creating a new Django project. Open a terminal and run the following command:
django-admin startproject chatapp
This will create a new directory named chatapp
with the basic structure of a Django project.
Change into the project directory:
cd chatapp
Next, create a new Django app within the project. Run the following command:
python manage.py startapp chat
This will create a new directory named chat
with the basic structure of a Django app.
Now, let’s add the newly created app to the INSTALLED_APPS
list in the settings.py
file:
INSTALLED_APPS = [
# ...
'chat',
# ...
]
Creating the Chat Model
We will start by creating a Chat
model to represent a chat room. Open the chat/models.py
file and add the following code:
from django.db import models
class Chat(models.Model):
name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
This model represents a basic chat room with a name and a creation timestamp. We will use this model to store information about individual chat rooms.
Run the following command to create the necessary database tables:
python manage.py migrate
Creating the Chat Room View
Next, let’s create the view that will display the chat room to users. Open the chat/views.py
file and add the following code:
from django.shortcuts import render
from django.views.generic import TemplateView
from .models import Chat
class ChatRoomView(TemplateView):
template_name = 'chat/chat_room.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['chats'] = Chat.objects.all()
return context
In this code, we are using Django’s TemplateView
class to render a template file named chat_room.html
. We also fetch all chat rooms from the database and pass them to the template context.
Creating the Chat Room Template
Create a new directory named templates
inside the chat
directory. Then, create a new file named chat_room.html
inside the templates
directory.
Open the chat/templates/chat_room.html
file and add the following code:
<!DOCTYPE html>
<html>
<head>
<title>Chat Room</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Chat Room</h1>
<div id="chats">
{% for chat in chats %}
<p>{{ chat.name }}</p>
{% endfor %}
</div>
<form id="chat-form" method="POST">
{% csrf_token %}
<input type="text" name="message" id="message" placeholder="Enter a message" />
<button type="submit">Send</button>
</form>
<script type="text/javascript">
$(document).ready(function() {
// Establish WebSocket connection
const socket = new WebSocket('ws://localhost:8000/ws/chat/');
// Handle incoming WebSocket messages
socket.onmessage = function(event) {
const message = JSON.parse(event.data);
$('#chats').append('<p>' + message.message + '</p>');
}
// Handle form submission
$('#chat-form').on('submit', function(event) {
event.preventDefault();
const message = $('#message').val();
socket.send(JSON.stringify({'message': message}));
$('#message').val('');
});
});
</script>
</body>
</html>
In this template, we are rendering the list of chat rooms and displaying a form for users to send messages. When the form is submitted, we send the message to the WebSocket server using the socket.send()
method.
Creating the WebSocket Consumer
Now, let’s create the WebSocket consumer that will handle WebSocket connections and messages. Create a new directory named consumers
inside the chat
directory. Then, create a new file named chat_consumer.py
inside the consumers
directory.
Open the chat/consumers/chat_consumer.py
file and add the following code:
from channels.generic.websocket import AsyncWebsocketConsumer
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.chat_name = self.scope['url_route']['kwargs']['chat_name']
self.chat_group_name = 'chat_%s' % self.chat_name
# Join chat room group
await self.channel_layer.group_add(
self.chat_group_name,
self.channel_name
)
await self.accept()
async def disconnect(self, close_code):
# Leave chat room group
await self.channel_layer.group_discard(
self.chat_group_name,
self.channel_name
)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
# Send message to chat room group
await self.channel_layer.group_send(
self.chat_group_name,
{
'type': 'chat_message',
'message': message
}
)
async def chat_message(self, event):
message = event['message']
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': message
}))
This ChatConsumer
class is a WebSocket consumer that handles the WebSocket connection, disconnection, and incoming messages. When a message is received, it sends the message to the chat room group, which broadcasts it to all connected clients.
Routing WebSocket URLs
To connect Django Channels to the WebSocket protocol, we need to define a routing configuration. Create a new file named routing.py
in the project directory.
Open the chatapp/routing.py
file and add the following code:
from django.urls import path
from .consumers import ChatConsumer
websocket_urlpatterns = [
path('ws/chat/<str_chat_name>/', ChatConsumer.as_asgi()),
]
In this code, we define a WebSocket URL pattern that matches the URL ws/chat/<chat_name>/
and maps it to the ChatConsumer
class.
Configuring ASGI Application
To enable Django Channels, we need to configure ASGI (Asynchronous Server Gateway Interface) application. Open the chatapp/asgi.py
file and update the following code:
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from chatapp.routing import websocket_urlpatterns
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chatapp.settings')
application = ProtocolTypeRouter(
{
'http': get_asgi_application(),
'websocket': URLRouter(websocket_urlpatterns)
}
)
This code sets up the ASGI application to handle both HTTP and WebSocket requests. The URLRouter
maps the WebSocket URLs to the appropriate consumers.
Updating the Project URL Configuration
Finally, we need to update the project URL configuration to include the chat app URLs. Open the chatapp/urls.py
file and add the following code:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('chat.urls')),
]
Running the Development Server
Now that we have finished setting up our chat application, let’s run the development server and test it out. In a terminal, run the following command:
python manage.py runserver
Open your web browser and visit http://localhost:8000/. You should see the chat room with a list of chat rooms and a form to send messages.
Open multiple browser windows or tabs and enter the same chat room. Send a message from one window, and you should see the message appear in real-time on all connected windows.
Congratulations! You have successfully built a chat application with Django Channels and WebSocket. Feel free to explore and extend the application further. You can add authentication, implement private messaging, or enhance the user interface.
Conclusion
In this tutorial, we learned how to build a real-time chat application using Django Channels and WebSocket. We covered the steps to set up the project, create the chat model, implement the chat room view and template, create the WebSocket consumer, configure the routing, and run the development server.
By using Django Channels and WebSocket, we were able to create a chat application that enables real-time communication between multiple users. This is just the beginning. You can expand on this application by adding more features to meet your specific requirements.
I hope this tutorial has been helpful in understanding how to build a chat application with Django Channels and WebSocket. Enjoy coding and building real-time applications with Django!