•2 min read•Tutorial
Building Dynamic UIs with HTMX and Django
Learn how to integrate HTMX with Django to build modern, interactive web applications with minimal JavaScript
Building Dynamic UIs with HTMX and Django
HTMX and Django are a perfect match. Django handles the backend, HTMX adds interactivity. No complex JavaScript frameworks needed.
Setup
pip install django django-htmx
# settings.py
INSTALLED_APPS = [
'django_htmx',
# ...
]
MIDDLEWARE = [
'django_htmx.middleware.HtmxMiddleware',
# ...
]
Basic Example
# views.py
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return render(request, 'index.html')
def load_users(request):
users = User.objects.all()
return render(request, 'partials/users.html', {'users': users})
<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
</head>
<body>
<button hx-get="{% url 'load_users' %}"
hx-target="#user-list">
Load Users
</button>
<div id="user-list"></div>
</body>
</html>
<!-- templates/partials/users.html -->
<ul>
{% for user in users %}
<li>{{ user.username }}</li>
{% endfor %}
</ul>
CRUD Operations
# models.py
from django.db import models
class Task(models.Model):
title = models.CharField(max_length=200)
completed = models.BooleanField(default=False)
# views.py
def task_list(request):
tasks = Task.objects.all()
return render(request, 'tasks.html', {'tasks': tasks})
def task_create(request):
if request.method == 'POST':
title = request.POST.get('title')
task = Task.objects.create(title=title)
return render(request, 'partials/task_item.html', {'task': task})
def task_update(request, pk):
task = Task.objects.get(pk=pk)
task.completed = not task.completed
task.save()
return render(request, 'partials/task_item.html', {'task': task})
def task_delete(request, pk):
Task.objects.filter(pk=pk).delete()
return HttpResponse('')
<!-- tasks.html -->
<form hx-post="{% url 'task_create' %}"
hx-target="#task-list"
hx-swap="beforeend">
{% csrf_token %}
<input name="title" placeholder="New task" required />
<button>Add</button>
</form>
<ul id="task-list">
{% for task in tasks %}
{% include 'partials/task_item.html' %}
{% endfor %}
</ul>
<!-- partials/task_item.html -->
<li id="task-{{ task.id }}">
<span style="{% if task.completed %}text-decoration: line-through{% endif %}">
{{ task.title }}
</span>
<button hx-put="{% url 'task_update' task.id %}"
hx-target="#task-{{ task.id }}"
hx-swap="outerHTML">
Toggle
</button>
<button hx-delete="{% url 'task_delete' task.id %}"
hx-target="#task-{{ task.id }}"
hx-swap="outerHTML">
Delete
</button>
</li>
Django + HTMX Best Practices
- Check HTMX requests
def my_view(request):
if request.htmx:
# Return partial template
return render(request, 'partials/content.html')
# Return full page
return render(request, 'page.html')
- Use HTMX headers
from django.http import HttpResponse
def my_view(request):
response = HttpResponse()
response['HX-Trigger'] = 'itemUpdated'
return response
- Class-based views
from django.views.generic import View
class TaskView(View):
def get(self, request):
tasks = Task.objects.all()
return render(request, 'tasks.html', {'tasks': tasks})
def post(self, request):
title = request.POST.get('title')
task = Task.objects.create(title=title)
return render(request, 'partials/task_item.html', {'task': task})
Conclusion
HTMX + Django = powerful, simple web apps. Server-side rendering with modern interactivity. Try it on your next project!
👨💻
Jordan Patel
Web Developer & Technology Enthusiast