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 authentication The 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 th
13 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
The most important part of a model and the only required part of a model is the list of database fields it defines. Fields are specified by class attributes. Be careful not to choose field names that conflict with the models API like clean, save, or delete. Example: from django.db import models clas
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 lets us interact with its database models, i.e. add, delete, modify, and query objects, using a database-abstraction API called ORM(Object Relational Mapper). This article discusses all the functional operations we can perform using Django ORM. Prerequisite: Django models Django ORM Django's
3 min read
Django Class Based Views
Django is a Python-based web framework that allows you to quickly create web applications. It has a built-in admin interface which makes it easy to work with it. It is often called a Class-Based included framework because it provides built-in facilities for every functionality. Class Based Generic V
10 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