The simplest way to add polling to Django with HTMX 🗳️

Photo of Tom Dekan
by Tom Dekan

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:

  1. Setup a Django app
  2. Add a data dashboard (showing new sales) with your Django app
  3. Add HTMX to update the dashboard every few seconds
  4. 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 the templates folder:

{% for purchase in purchases %}
    {%  include 'table-row.html' with purchase=purchase %}
{% endfor %}
  • Add the following template called table-row.html to the templates 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 the templates 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>

4. Style the dashboard (Optional - using Photon Designer)

I'll use Photon Designer (my product) to generate styling for the dashboard.

  • Go to Photon Designer,
  • Activate Django mode, paste in your templates
  • Add the prompt: "Generate amazing styling for my sales dashboard"

P.S Photon Designer

Do you dream of creating Django products so quickly they break the space-time continuum? Yeah, me too.

I'm building: Photon Designer -> Currently free to use

Let's get visual.

Do you want to create beautiful frontends effortlessly?
Click below to book your spot on our early access mailing list (as well as early adopter prices).
Copied link to clipboard 📋

Made with care by Tom Dekan

© 2024 Photon Designer