The simplest way to add polling to Django with HTMX 🗳️
Published: May 16, 2024
So, you want to update your data every few seconds? I'll show you how to add polling to Django with HTMX (HTMX lets you add javascript without writing any javascript).
There will be 4 super simple steps:
- Setup a Django app
- Add a data dashboard (showing new sales) with your Django app
- Add HTMX to update the dashboard every few seconds
- Style the dashboard
Here's my final styled output, after using a draft from Photon Designer:
And here's a video guide (following the below written guide) featuring me 🙂:
1. Setup a Django app
pip install --upgrade django faker
django-admin startproject core .
python manage.py startapp sim
- Add our app sim to the
INSTALLED_APPS
in settings.py:
# settings.py
INSTALLED_APPS = [
'sim',
...
]
2. Add a data dashboard (showing new sales)
Add your views
- Add the following views to your views.py file:
from django.shortcuts import render
from faker import Faker
from random import randint
fake = Faker()
def index(request):
purchases = [
{"name": "Computing for Beginners", "category": "Book", "price": "$29.99", "buyer": "mr-celloist1@gmail.com"},
{"name": "Computing for Beginners", "category": "Book", "price": "$29.99", "buyer": "ztod-a@gmail.com"},
{"name": "Why the President is secretly turning into a cat - And not how you think", "category": "Video", "price": "$9.75", "buyer": "alex.g@gmail.com"},
{"name": "Computing for Beginners", "category": "Book", "price": "$29.99", "buyer": "rob.moggak@gmail.com"},
]
return render(request, 'index.html', context={"purchases": purchases})
def get_new_purchases(request):
new_purchases = []
for _ in range(randint(0, 2)): # generate random purchases.
purchase = {
"name": f"Computing for a {fake.job()}",
"category": "Book",
"price": f"${randint(10, 100)}.{randint(0, 99)}",
"buyer": fake.email()
}
new_purchases.append(purchase)
return render(request, 'table-rows.html', context={"purchases": new_purchases})
Add your templates
-
Create a new folder called
templates
in the sim app folder -
Add the following template called
table-rows.html
to thetemplates
folder:
{% for purchase in purchases %} {% include 'table-row.html' with
purchase=purchase %} {% endfor %}
- Add the following template called
table-row.html
to thetemplates
folder:
<tr>
<td>
<span>{{ purchase.price }}</span>
</td>
<td>{{ purchase.name }}</td>
<td>{{ purchase.category }}</td>
<td>{{ purchase.buyer }}</td>
<td>{% now 'H:m:s d/m/Y' %}</td>
<td><a>More</a></td>
</tr>
- Add the following template called
index.html
to thetemplates
folder:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
src="https://unpkg.com/htmx.org@1.9.12"
integrity="sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2"
crossorigin="anonymous"
></script>
<script src="https://cdn.tailwindcss.com"></script>
<title>Sales</title>
</head>
<div>
<header>Your Sales on {% now 'D M Y' %}</header>
<div>
<div>
<div>
<table>
<thead>
<tr>
<th>Price</th>
<th>Product</th>
<th>Category</th>
<th>Customer</th>
<th>Time</th>
<th><span>More</span></th>
</tr>
</thead>
<tbody id="table-body">
{% include 'table-rows.html' with purchases=purchases %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</html>
Add your urls
- Add the following urls to your core/urls.py file:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('sim.urls')),
]
- Create a new file called
urls.py
in the sim app folder and add the following:
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('get-new-purchases', views.get_new_purchases, name='get-new-purchases'),
]
3. Add htmx to update the dashboard every few seconds
- Update your
index.html
template to be the following:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
src="https://unpkg.com/htmx.org@1.9.12"
integrity="sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2"
crossorigin="anonymous"
></script>
<script src="https://cdn.tailwindcss.com"></script>
<title>Sales</title>
</head>
<div>
<header>Your Sales on {% now 'D M Y' %}</header>
<div>
<div>
<div>
<table>
<thead>
<tr>
<th>Price</th>
<th>Product</th>
<th>Category</th>
<th>Customer</th>
<th>Time</th>
<th>
<span>Edit</span>
</th>
</tr>
</thead>
<tbody id="table-body">
{% include 'table-rows.html' with purchases=purchases %}
<div
hx-get="/get-new-purchases"
hx-trigger="every 2s"
hx-swap="afterbegin"
hx-target="#table-body"
></div>
</tbody>
</table>
</div>
</div>
</div>
</div>
</html>
That's it! You've just added polling to your Django app with HTMX.