Django Channels - Introduction and Basic Setup
Last Updated :
24 Sep, 2024
Django is a powerful Python framework for web development. It is fast, secure, and reliable. Channels allow Django projects to handle HTTP along with asynchronous protocols like WebSockets, MQTT, chatbots, and more.
Channels:
Channels preserve the synchronous behavior of Django and add a layer of asynchronous protocols allowing users to write the views that are entirely synchronous, asynchronous, or a mixture of both. Channels basically allow the application to support "long-running connections". It replaces Django's default WSGI with its ASGI .
Django Channels allow for handling WebSockets, and understanding this can elevate your web development skills. The Complete Django Web Development Course - Basics to Advance provides a deeper exploration of Django Channels and other advanced topics."
ASGI:
ASGI (Asynchronous Server Gateway Interface) provides an interface between async Python web servers and applications while it supports all the features provided by WSGI.
Consumers:
A consumer is a basic unit of Channels. It is an event-driven class that supports both async and sync applications. Consumers can run longer and hence they support web sockets that need persistent connection.
In this post, we will set up a basic example of channels. We will build a calculator app that will allow the user to send multiple expressions to the server and receive the result through a single persistent connection.
Environment Setup:
- It is always a good idea to create a virtual environment for the python apps in order to avoid version conflicts. Run the following commands in the terminal to get started
easy-install pip
python3 -m pip install virtualenv
virtualenv venv
source venv/bin/activate
- Now install Django and Channels :
pip install django
pip install channels
# On windows, try an unofficial wheel of 'Twisted' in case of dependency errors
LiveCalculator App:
Now start a Django project and create an app named 'liveCalculator'
django-admin startproject sampleProject
cd sampleProject
python3 manage.py startapp liveCalculator
In sampleProject/settings.py , register channels and liveCalculator .
settings.py:
INSTALLED_APPS = [
'channels',
'liveCalculator',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
In sampleProject/asgi.py, add the http protocol.
asgi.py:
Python
import os
import django
from channels.http import AsgiHandler
from channels.routing import ProtocolTypeRouter
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sampleProject.settings')
django.setup()
application = ProtocolTypeRouter({
"http": AsgiHandler(),
# Just HTTP for now. (We can add other protocols later.)
})
Now we need to register this asgi into our application. Add this line in sampleProject/settings.py :
ASGI_APPLICATION = "sampleProject.asgi.application"
Create a new folder liveCalculator/templates/liveCalculator and create a new file index.html inside it. It will be the starting page of our app. Add the following code in index.html:
index.html:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Calculator</title>
</head>
<body>
<textarea name="ta" id="results" cols="30" rows="10">
</textarea><br>
Enter the expression: <input type="text" id="exp">
<input type="button" id="submit" value="Get Results">
<script>
const socket = new WebSocket('ws://localhost:8000/ws/livec/');
socket.onmessage = (e) => {
result = JSON.parse(e.data).result;
document.getElementById("results").value += "Server: " + result + "\n";
}
socket.onclose = (e) => {
console.log("Socket closed!");
}
document.querySelector('#exp').onkeyup = function (e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#submit ').click();
}
};
document.querySelector("#submit").onclick = (e) => {
inputfield = document.querySelector("#exp")
exp = inputfield.value
socket.send(JSON.stringify(
{
expression: exp
}
))
document.querySelector("#results").value += "You: " + exp + "\n";
inputfield.value = "";
}
</script>
</body>
</html>
The above code will render a text area and an input box where the user can enter the expression. It will create a socket connection that we will make later and append the received result in the text area. When the user inputs the expression, it will send the expression through a socket connection.
Now create a view to render this page in liveCalculator/views.py :
liveCalculator/views.py:
Python
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, 'liveCalculator/index.html', {})
Next, we need to create a route for this view. Add a new file urls.py in liveCalculator directory and add the following code:
liveCalculator/urls.py:
Python
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name="index"),
]
Register this route in sampleProject/urls.py :
sampleProject/urls.py:
Python
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^', include('liveCalculator.urls'))
]
Now we need to create the consumer for our web socket connection. We will use the generic WebsocketConsumer class to implement its event-driven methods. Create a new file consumers.py in liveCalculator folder and add the following code:
consumers.py:
Python
import json
from channels.generic.websocket import WebsocketConsumer
class Calculator(WebsocketConsumer):
def connect(self):
self.accept()
def disconnect(self, close_code):
self.close()
def receive(self, text_data):
text_data_json = json.loads(text_data)
expression = text_data_json['expression']
try:
result = eval(expression)
except Exception as e:
result = "Invalid Expression"
self.send(text_data=json.dumps({
'result': result
}))
The WebsocketConsumer class supports these user-defined methods:
- connect() : We can write the business logic of what should happen when the client sends a connection request.
- disconnect() : We can write the business logic of what should happen when the client sends a disconnection request.
- receive(): We can write the business logic of what should happen when the client sends a message.
It also supports these built-in methods:
- accept(): It will accept the incoming connection.
- close(): It will close the current connection.
- send(): It will send the specified message to the client.
We have simply used the above methods in our Calculator class to accept the connection, evaluate the expression when a message a received, and send it to the client.
Next, we also need to define the routing method for this consumer. Create a new file routing.py in the same folder and add the following code to it:
routing.py:
Python
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/livec/$', consumers.Calculator.as_asgi()),
]
Note that we have used as_asgi() method on our Calculator class to use it for our application. This will enable the socket on ws://<IP:Port>/ws/livec . Now register routing.py into asgi.py by declaring the WebSocket protocol.
asgi.py:
Python
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import liveCalculator.routing
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sampleProject.settings")
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
liveCalculator.routing.websocket_urlpatterns
)
),
})
We are almost done with our first Channels application. Save all the files and run the following commands in the terminal:
python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py runserver
Now open http://localhost:8000 on your browser, and you should see the output like this:
See the log of the server. Note that we have created the connection only once, and we can send the message multiple times without creating a new connection.
Similar Reads
Django Introduction | Set 2 (Creating a Project)
Note- This article is in continuation of Django introduction. Popularity of Django Django is used in many popular sites like as: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic etc. There are more than 5k online sites based on Django framework. ( Source ) Si
3 min read
Token Authentication in Django Channels and Websockets
Prerequisites: Django, WebSockets, Django channels, Token authenticationThe most popular Django topics right now are WebSockets and Django channels because they make it possible to communicate quickly and easily while working in real-time without constantly refreshing the page. When working with the
12 min read
Top 50 Django Interview Questions and Answers
Django is one of the high-level Python-based free and open-source web frameworks and was created in 2003. It follows the model-view-template (MVT) architectural pattern. Nowadays, It is one of the most demanding skills. It has been managed by Django Software Foundation (DSF), a Non-benefit Organizat
15+ min read
How to Create an App in Django ?
Prerequisite - How to Create a Basic Project using MVT in Django? Django is famous for its unique and fully managed app structure. For every functionality, an app can be created like a completely independent module. This article will take you through how to create a basic app and add functionalities
4 min read
Django model data types and fields list
Django models represent the structure of your database tables, and fields are the core components of those models. Fields define the type of data each database column can hold and how it should behave. This artcle covers all major Django model field types and their usage.Defining Fields in a ModelEa
4 min read
Django - Creating apps | Set - 2
In the previous article, we discussed why apps are important in Django project management? What are the benefits of using Django apps? In this article, we will discuss what are we going to build and how do apps play a vital role in Django projects? Project outline - We will build a localhost e-comme
2 min read
Django ORM - Inserting, Updating & Deleting Data
Django's Object-Relational Mapping (ORM) is one of the key features that simplifies interaction with the database. It allows developers to define their database schema in Python classes and manage data without writing raw SQL queries. The Django ORM bridges the gap between Python objects and databas
4 min read
Django Class Based Views
Class-Based Views (CBVs) allow developers to handle HTTP requests in a structured and reusable way. With CBVs, different HTTP methods (like GET, POST) are handled as separate methods in a class, which helps with code organization and reusability.Advantages of CBVsSeparation of Logic: CBVs separate d
6 min read
Create an Audio Editor in Python using PyDub
Audio editing is a crucial aspect of modern multimedia production, from music production to podcasting and video editing. Python, with its extensive libraries and tools, offers a versatile platform for audio editing tasks. Among these libraries, PyDub stands out as a powerful and user-friendly libra
7 min read
Realtime chat app using Django
Chat Room has been the most basic step toward creating real-time and live projects. The chat page that we will create will be a simple HTML boilerplate with a simple h1 text with the name of the current user and a link to log out to the user who is just logged in. You may need to comment on the line
11 min read