I just want to create a project to view the real-time output from the ‘templates/index.html’ without refreshing the page. Additionally, there is no need to insert data into the database using the template, as I use Django admin to insert data manually. Web Socket connects perfectly.
I just want to create a project to view the real-time output from the ‘templates/index.html’ without refreshing the page. Additionally, there is no need to insert data into the database using the template, as I use Django admin to insert data manually. Web Socket connects perfectly.
views.py
from django.shortcuts import render
from .models import MyModel
def index(request):
people = MyModel.objects.all()
return render(request, ‘index.html’, {‘people’: people})
realapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path(‘’, views.index, name=‘index.html’),
]
realtime/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘’, include(‘realapp.urls’)),
]
My Realtime App
<!doctype html>
Realtime App My Realtime App
var socket = new WebSocket(‘ws://127.0.0.1:9000/ws/real/’);
socket.onmessage = function(event) {
var data = JSON.parse(event.data);
var message = data.message;
document.getElementById('realtime-data').innerHTML = message;
};
socket.onopen = function(event) {
socket.send(JSON.stringify({
'message': 'Hello, server!'
}));
};
</script>
realapp/models.py
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=100)
desc = models.CharField(max_length=200)
realapp/admin.py
from django.contrib import admin
from .models import MyModel
admin.site.register(MyModel)
realtime/asgi.py
#settings.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from realapp.routing import websocket_urlpatterns # Import your WebSocket URL patterns
os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘realtime.settings’)
application = ProtocolTypeRouter({
“http”: get_asgi_application(),
“websocket”: AuthMiddlewareStack(
URLRouter(
websocket_urlpatterns
)
),
})
realapp/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from asgiref.sync import async_to_sync
class RealtimeConsumer(AsyncWebsocketConsumer):
async def connect(self):
await self.channel_layer.group_add(‘realtime_group’, self.channel_name)
await self.accept()
async def disconnect(self, close_code):
await self.channel_layer.group_discard(‘realtime_group’, self.channel_name)
async def receive(self, text_data):
data = json.loads(text_data)
message = data['message']
await self.channel_layer.group_send(
'realtime_group',
{
'type': 'realtime_message',
'message': message
}
)
async def realtime_message(self, event):
message = event[‘message’]
await self.send(text_data=json.dumps({
'message': message
}))
realapp/routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r’ws/real/$', consumers.RealtimeConsumer.as_asgi()),
]
settings.py
from pathlib import Path
import os
BASE_DIR = Path(file).resolve().parent.parent
SECRET_KEY = ‘django-insecure-6d5f@scw%v-kmse5w8hdmo9fyxka07)$mu)24&t*x7&_v(ln8v’
DEBUG = True
ALLOWED_HOSTS =
INSTALLED_APPS = [
‘channels’,
‘realapp’,
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
]
MIDDLEWARE = [
‘django.middleware.security.SecurityMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
‘django.middleware.common.CommonMiddleware’,
‘django.middleware.csrf.CsrfViewMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
‘django.contrib.messages.middleware.MessageMiddleware’,
‘django.middleware.clickjacking.XFrameOptionsMiddleware’,
]
ROOT_URLCONF = ‘realtime.urls’
TEMPLATES = [
{
‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,
‘DIRS’: ,
‘APP_DIRS’: True,
‘OPTIONS’: {
‘context_processors’: [
‘django.template.context_processors.debug’,
‘django.template.context_processors.request’,
‘django.contrib.auth.context_processors.auth’,
‘django.contrib.messages.context_processors.messages’,
],
},
},
]
ASGI_APPLICATION = ‘realtime.routing.application’
CHANNEL_LAYERS = {
‘default’: {
‘BACKEND’: ‘channels.layers.InMemoryChannelLayer’, # Use InMemoryChannelLayer for development
},
}
DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.sqlite3’,
‘NAME’: BASE_DIR / ‘db.sqlite3’,
}
}
AUTH_PASSWORD_VALIDATORS = [
{
‘NAME’: ‘django.contrib.auth.password_validation.UserAttributeSimilarityValidator’,
},
{
‘NAME’: ‘django.contrib.auth.password_validation.MinimumLengthValidator’,
},
{
‘NAME’: ‘django.contrib.auth.password_validation.CommonPasswordValidator’,
},
{
‘NAME’: ‘django.contrib.auth.password_validation.NumericPasswordValidator’,
},
]
LANGUAGE_CODE = ‘en-us’
TIME_ZONE = ‘UTC’
USE_I18N = True
USE_TZ = True
STATIC_URL = ‘/static/’
STATIC_ROOT = os.path.join(BASE_DIR, ‘staticfiles’)
DEFAULT_AUTO_FIELD = ‘django.db.models.BigAutoField’
Folder Structure
.
├── db.sqlite3
├── manage.py
├── realapp
│ ├── admin.py
│ ├── apps.py
│ ├── consumers.py
│ ├── init.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── init.py
│ │ └── pycache
│ │ ├── 0001_initial.cpython-310.pyc
│ │ └── init.cpython-310.pyc
│ ├── models.py
│ ├── pycache
│ │ ├── admin.cpython-310.pyc
│ │ ├── apps.cpython-310.pyc
│ │ ├── consumers.cpython-310.pyc
│ │ ├── init.cpython-310.pyc
│ │ ├── models.cpython-310.pyc
│ │ ├── routing.cpython-310.pyc
│ │ ├── urls.cpython-310.pyc
│ │ └── views.cpython-310.pyc
│ ├── routing.py
│ ├── templates
│ │ └── index.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── realtime
│ ├── asgi.py
│ ├── init.py
│ ├── pycache
│ │ ├── asgi.cpython-310.pyc
│ │ ├── init.cpython-310.pyc
│ │ ├── settings.cpython-310.pyc
│ │ ├── urls.cpython-310.pyc
│ │ └── wsgi.cpython-310.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── staticfiles
└── admin
├── css
│ ├── autocomplete.css
│ ├── base.css
│ ├── changelists.css
│ ├── dark_mode.css
│ ├── dashboard.css
│ ├── forms.css
│ ├── login.css
│ ├── nav_sidebar.css
│ ├── responsive.css
│ ├── responsive_rtl.css
│ ├── rtl.css
│ ├── vendor
│ │ └── select2
│ │ ├── LICENSE-SELECT2.md
│ │ ├── select2.css
│ │ └── select2.min.css
│ └── widgets.css
├── img
│ ├── calendar-icons.svg
│ ├── gis
│ │ ├── move_vertex_off.svg
│ │ └── move_vertex_on.svg
│ ├── icon-addlink.svg
│ ├── icon-alert.svg
│ ├── icon-calendar.svg
│ ├── icon-changelink.svg
│ ├── icon-clock.svg
│ ├── icon-deletelink.svg
│ ├── icon-no.svg
│ ├── icon-unknown-alt.svg
│ ├── icon-unknown.svg
│ ├── icon-viewlink.svg
│ ├── icon-yes.svg
│ ├── inline-delete.svg
│ ├── LICENSE
│ ├── README.txt
│ ├── search.svg
│ ├── selector-icons.svg
│ ├── sorting-icons.svg
│ ├── tooltag-add.svg
│ └── tooltag-arrowright.svg
└── js
├── actions.js
├── admin
│ ├── DateTimeShortcuts.js
│ └── RelatedObjectLookups.js
├── autocomplete.js
├── calendar.js
├── cancel.js
├── change_form.js
├── collapse.js
├── core.js
├── filters.js
├── inlines.js
├── jquery.init.js
├── nav_sidebar.js
├── popup_response.js
├── prepopulate_init.js
├── prepopulate.js
├── SelectBox.js
├── SelectFilter2.js
├── theme.js
├── urlify.js
└── vendor
├── jquery
│ ├── jquery.js
│ ├── jquery.min.js
│ └── LICENSE.txt
├── select2
│ ├── i18n
│ │ ├── af.js
│ │ ├── ar.js
│ │ ├── az.js
│ │ ├── bg.js
│ │ ├── bn.js
│ │ ├── bs.js
│ │ ├── ca.js
│ │ ├── cs.js
│ │ ├── da.js
│ │ ├── de.js
│ │ ├── dsb.js
│ │ ├── el.js
│ │ ├── en.js
│ │ ├── es.js
│ │ ├── et.js
│ │ ├── eu.js
│ │ ├── fa.js
│ │ ├── fi.js
│ │ ├── fr.js
│ │ ├── gl.js
│ │ ├── he.js
│ │ ├── hi.js
│ │ ├── hr.js
│ │ ├── hsb.js
│ │ ├── hu.js
│ │ ├── hy.js
│ │ ├── id.js
│ │ ├── is.js
│ │ ├── it.js
│ │ ├── ja.js
│ │ ├── ka.js
│ │ ├── km.js
│ │ ├── ko.js
│ │ ├── lt.js
│ │ ├── lv.js
│ │ ├── mk.js
│ │ ├── ms.js
│ │ ├── nb.js
│ │ ├── ne.js
│ │ ├── nl.js
│ │ ├── pl.js
│ │ ├── ps.js
│ │ ├── pt-BR.js
│ │ ├── pt.js
│ │ ├── ro.js
│ │ ├── ru.js
│ │ ├── sk.js
│ │ ├── sl.js
│ │ ├── sq.js
│ │ ├── sr-Cyrl.js
│ │ ├── sr.js
│ │ ├── sv.js
│ │ ├── th.js
│ │ ├── tk.js
│ │ ├── tr.js
│ │ ├── uk.js
│ │ ├── vi.js
│ │ ├── zh-CN.js
│ │ └── zh-TW.js
│ ├── LICENSE.md
│ ├── select2.full.js
│ └── select2.full.min.js
└── xregexp
├── LICENSE.txt
├── xregexp.js
└── xregexp.min.js
21 directories, 159 files