Django Live Search with HTMX
Reference https://www.djangoproject.com/ and https://htmx.org/
Note: Django Admin in story used for add movies data.
Step 1: Preparation, Create Django Project, Inital Migration
create virtualenv: virtualenv venv
start virtualenv: venv/Scripts/activate
install Django in virtualenv: pip install django==4.2
Create Django: django-admin startproject myproject
Go to myproject folder: cd myproject
Initial Migration: python manage.py migrate
Step 2: Create Django Apps
Create apps: python manage.py startapp myapp
Step 3: Project Setting: Register Apps, Set Templates Folder (myproject/settings.py)
...
INSTALLED_APPS = [
...
'myapp', #updated
]
...
TEMPLATES = [
...
'DIRS': [Path(BASE_DIR, 'templates')], #updated
...
]
...
Step 4: Add Model in myapp/models.py
from django.db import models
# Create your models here.
class Movie(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(max_length=1000)
year = models.IntegerField(default=2000)
Step 5: Register Model in Django Admin
from django.contrib import admin
from .models import Movie
class MovieAdmin(admin.ModelAdmin):
list_display = ('title', 'description', 'year')
admin.site.register(Movie, MovieAdmin)
Step 6: Makemigrations and Migrate
Make migrations: python manage.py makemigrations
Migrate: python manage.py migrate
Step 7: Create HTML Files in Templates Folder
Create templates folder in main app
Create templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Title</title>
</head>
<body>
<input type="search"
name="keyword" placeholder="Search movies..."
hx-post="{% url 'list' %}"
hx-trigger="load, input changed delay:500ms, keyword"
hx-target="#search-results"
hx-indicator=".htmx-indicator"
hx-headers='{"X-CSRFToken":"{{ csrf_token }}"}'
>
<br>
<span class="htmx-indicator" >
Searching...
</span>
<div id="search-results">
</div>
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
</body>
</html>
Create templates/list.html
{% if movies %}
{% for movie in movies %}
<h3>{{movie.title}} ({{movie.year}})</h3>
<p>{{movie.description }}</p>
{% endfor %}
{% else %}
<p>No result</p>
{% endif %}
Step 8: Create Function Views myapp/views.py
from django.shortcuts import render
from .models import Movie
# Create your views here.
def index(request):
template = 'index.html'
extra_context = {}
return render(request, template, extra_context)
def list(request):
template = 'list.html'
keyword = request.POST.get("keyword")
movies = Movie.objects.filter(title__icontains=keyword) #search title by keyword
extra_context = {'movies': movies}
return render(request, template, extra_context)
Step 9: Setup URLS
Create myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("list/", views.list, name="list"),
]
Update myproject/urls.py
from django.contrib import admin
from django.urls import path, include #updated
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')), #updated
]
Step 10: Create Superuser
Create superuser: python manage.py createsuperuser
Type username, email password and retype password
Step 11: Run Server and Testing
Run Server: python manage.py runserver
Testing:
a. Login in Django Admin and add movies http://127.0.0.1:8000/admin
b. Open http://127.0.0.1:8000/