Simple guide to setup django-htmx in a django project. In this guide we assume that you already have a django project setup in a virtualenv and you only wish to add django-htmx to your project.
-
Install the django-htmx package
pip install django-htmx
-
Add django-htmx to your
INSTALLED_APPS
:INSTALLED_APPS = [ ..., "django_htmx", ..., ]
-
Add the middleware:
MIDDLEWARE = [ ..., "django_htmx.middleware.HtmxMiddleware", ..., ]
-
Load and use the htmx template tags in your base template file.
<!-- base.html --> {% load django_htmx %} <!DOCTYPE html> <html lang="en"> <body> ... <script defer src="{% static 'js/htmx.js' %}"></script> {% django_htmx_script %} </body> </html>
Download the htmx js file or use the cdn :
https://unpkg.com/[email protected]
You can already get all of this from the django-htmx github page, now the example with a django class base view.
# viewmixins.py
class HtmxView:
success_url = "."
@property
def htmx_template(self) -> str:
raise NotImplementedError
@property
def htmx_partial(self) -> str:
raise NotImplementedError
@property
def template_name(self) -> str:
return self.htmx_partial if self.request.htmx else self.htmx_template # noqa
With this simple mixin you can specify the html part you want to return when a request is made via htmx.
# views.py
from django.views.generic import FormView
from .forms import ContactForm
from .viewmixins import HtmxView
class ContactView(HtmxView, FormView):
form_class = ContactForm
htmx_partial = "partials/contact_form.html"
htmx_template = "pages/contact.html"
If you prefer function based views, you can use the decorator below.
# decorators.py
from functools import wraps
from django.shortcuts import render
def htmx_view(htmx_template: str, htmx_partial: str):
def inner(view):
@wraps(view)
def func(request, *args, **kwargs):
context: dict = view(request, *args, **kwargs)
template = htmx_partial if request.htmx else htmx_template
return render(request, template, context)
return func
return inner
# views.py
from .decorators import htmx_view
@htmx_view(htmx_template="pages/contact.html", htmx_partial="partials/contact_form.html")
def contact(request):
return {"form": ContactForm()}