Skip to content

Instantly share code, notes, and snippets.

@Tobi-De
Last active March 27, 2025 20:15
Show Gist options
  • Save Tobi-De/31535e7434956b6269afac84e147cfce to your computer and use it in GitHub Desktop.
Save Tobi-De/31535e7434956b6269afac84e147cfce to your computer and use it in GitHub Desktop.
Simple django CBV using django-htmx

Django-htmx guide setup

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.

  1. Install the django-htmx package

     pip install django-htmx
    
  2. Add django-htmx to your INSTALLED_APPS:

    INSTALLED_APPS = [
        ...,
        "django_htmx",
        ...,
    ]
    
  3. Add the middleware:

    MIDDLEWARE = [
        ...,
        "django_htmx.middleware.HtmxMiddleware",
        ...,
    ]
    
  4. 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()}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment