DjangoChannelsChatApp
Discover the code for a real-time chat website using Django Channels and WebSockets. Explore the complete source to enhance your Django and WebSocket skills. Elevate your understanding of real-time features in Django applications with this concise GitHub repository.
Install / Use
/learn @TheProtonGuy/DjangoChannelsChatAppREADME
Chat Website with Django and Django Channels
This tutorial will guide you through creating a chat website using Django and Django Channels.
Getting Started
1. Setting up a Django Project
-
Create and enter the desired directory for project setup.
-
Create a virtual environment using pipenv or other means:
pipenv shell -
Install Django:
pip install django -
Create a Django project called ChatPrj:
django-admin startproject ChatPrj -
Create an app called ChatApp:
python manage.py startapp ChatApp -
Open the project in your code editor.
-
Create a templates folder and register it in the project's settings.
-
Register the app in the project's settings.
-
Create URLs for the app and register them in the project's URLs.
2. Installing Libraries
-
Install Django Channels:
pip install django-channels -
Install Daphne:
pip install daphne -
Add ChatApp, daphne and channels to
installed_appsinsettings.pyfile:INSTALLED_APPS = [ 'daphne', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'ChatApp', 'channels', ]
3. Create Important Files in the App Folder
-
Create
routing.py. -
Create
consumers.py.
4. Creating Models
-
Create a model called
Room:class Room(models.Model): room_name = models.CharField(max_length=255) def __str(self): return self.room_name -
Create another model called
Message:class Message(models.Model): room = models.ForeignKey(Room, on_delete=models.CASCADE) sender = models.CharField(max_length=255) message = models.TextField() def __str(self): return str(self.room) -
Make migrations and migrate:
python manage.py makemigrations python manage.py migrate -
Register the models in the
admin.pyfile:from .models import * admin.site.register(Room) admin.site.register(Message)
5. Getting Template Files from GitHub
- Download the following HTML templates from GitHub:
index.htmlmessage.html
6. Create Views
-
CreateRoom view:
def CreateRoom(request): return render(request, 'index.html') -
Message view:
def MessageView(request, room_name, username): return render(request, 'message.html')
7. Map Views to URLs:
from . import views
from django.urls import path
urlpatterns = [
path('', views.CreateRoom, name='create-room'),
path('<str:room_name>/<str:username>/', views.MessageView, name='room'),
]
8. View CreateRoom view in browser to make sure setup works
9. Allow users to login or create chat rooms in CreateRoom view
In your index.html file, make sure to include a CSRF token in form:
{% csrf_token %}
In your Django CreateRoom view, check for incoming POST requests:
if request.method == 'POST':
Retrieve user-entered data:
if request.method == 'POST':
username = request.POST['username']
room = request.POST['room']
Create try and except blocks to either get the room object or create it if it does not exist:
try:
get_room = Room.objects.get(room_name=room)
except Room.DoesNotExist:
new_room = Room(room_name=room)
new_room.save()
Test the code to see if it works.
Next, redirect users to MessageView:
try:
get_room = Room.objects.get(room_name=room)
return redirect('room', room_name=room, username=username)
except Room.DoesNotExist:
new_room = Room(room_name=room)
new_room.save()
return redirect('room', room_name=room, username=username)
10. Displaying Messages Created in a Room
- Getting the room object and returning it as well as room name and username in the context
def MessageView(request, room_name, username):
get_room = Room.objects.get(room_name=room_name)
get_messages = Message.objects.filter(room=get_room)
context = {
"messages": get_messages,
"user": username,
"room_name": room_name,
}
return render(request, 'message.html', context)
- Display Messages from the Query Set in
message.html:
<div class="message" id="chatContainer">
<!-- Received messages are displayed here -->
{% for i in messages %}
{% if i.sender != user %}
<div class="receive">
<p style="color: #000;"> {{i.message}}<strong>-{{i.sender}}</strong></p>
</div>
{% else %}
<div class="send">
<p style="color: #000;">{{i.message}}</p>
</div>
{% endif %}
{% endfor %}
<!-- End of received messages -->
</div>
This code is part of your messages.html file and is responsible for rendering the messages in the chat room. Messages are displayed differently based on whether the sender is the current user or another user.
11. Creating Consumers
Head over to your consumers.py file
- Importing Modules:
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from ChatApp.models import *
- Creating
ChatConsumer:
class ChatConsumer(AsyncWebsocketConsumer):
- Create
connectMethod:
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = f"room_{self.scope['url_route']['kwargs']['room_name']}"
await self.channel_layer.group_add(self.room_name, self.channel_name)
await self.accept()
- Create
disconnectMethod:
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = f"room_{self.scope['url_route']['kwargs']['room_name']}"
await self.channel_layer.group_add(self.room_name, self.channel_name)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(self.room_name, self.channel_name)
In this code section, you're creating a Django Channels consumer called ChatConsumer. It includes the connect method for WebSocket connection setup and the disconnect method for WebSocket disconnection handling. These consumers are essential for real-time communication in your Django application.
12. Creating URL for ChatConsumer
Head to your routing.py File and Add the Following:
from django.urls import path
from .consumers import ChatConsumer
websocket_urlpatterns = [
path('ws/notification/<str:room_name>/', ChatConsumer.as_asgi()),
]
13. Register routing url in asgi.py file in project
Head to your asgi.py file in project folder
- Importing Modules:
import os
from django.core.asgi import get_asgi_application
# imports
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from ChatApp import routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'movie.settings')
application = get_asgi_application()
- Rename
applicationtodjango_asgi_app:
django_asgi_app = get_asgi_application()
- Add the Following:
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": URLRouter(
routing.websocket_urlpatterns
)
})
- The Final Code:
import os
from django.core.asgi import get_asgi_application
# imports
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from ChatApp import routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'movie.settings')
django_asgi_app = get_asgi_application()
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": URLRouter(
routing.websocket_urlpatterns
)
})
14. Adding asgi.py Configurations and channel_layers to Settings
Head to settings.py file
- Update
ASGI_APPLICATIONin your Settings:
ASGI_APPLICATION = "ChatProject.asgi.application"
- Add
channel_layersConfiguration:
CHANNEL_LAYERS = {
"default": {"BACKEND": "channels.layers.InMemoryChannelLayer"},
}
Here's the provided content in markdown format for your readme.md file:
15. Creating a New WebSocket
- Head to
message.htmlFile and Create Script Tags:
<script>
</script>
This step involves adding script tags to your message.html file to embed JavaScript code for handling WebSocket connections.
- Create a New WebSocket:
<script>
const websocketProtocol = window.location.protocol === "https:" ? "wss" : "ws";
const wsEndpoint = `${websocketProtocol}://${window.location.host}/ws/notification/{{room_name}}/`;
const socket = new WebSocket(wsEndpoint);
</script>
In this part of the code, you're creating a new WebSocket connection in your message.html file. It determines the WebSocket protocol based on whether the application is served over HTTPS or HTTP and establishes a connection to the WebSocket endpoint for the specific chat room.
16. Creating Event Handlers for WebSocket Connection
Handling WebSocket Connection Events:
<script>
// Determine the WebSocket protocol based on the application's URL
const websocketProtocol = window.location.protocol === "https:" ? "wss" : "ws";
const wsEndpoint = `${websocketProtocol}://${window.location.host}/ws/notification/{{room_name}}/`;
// Create a new WebSocket connection
