{"id":4508,"library":"django-htmx","title":"Django HTMX","description":"django-htmx is a Python package that provides extensions for integrating Django with htmx. It simplifies building dynamic and interactive web applications by offering middleware, template tags, and HTTP response utilities, allowing developers to leverage htmx's capabilities without writing extensive JavaScript. The library is actively maintained with a regular release cadence, ensuring compatibility with recent Django and Python versions.","status":"active","version":"1.27.0","language":"en","source_language":"en","source_url":"https://github.com/adamchainz/django-htmx","tags":["django","htmx","frontend","web","ajax","server-side rendering"],"install":[{"cmd":"pip install django-htmx","lang":"bash","label":"Install package"}],"dependencies":[{"reason":"Core framework dependency. Supports Django 4.2 to 6.0.","package":"Django","optional":false},{"reason":"The JavaScript library that django-htmx extends. Must be included in templates via CDN or static files.","package":"htmx.org (client-side JS library)","optional":false}],"imports":[{"note":"Required to enable `request.htmx` and other htmx-specific request processing.","symbol":"HtmxMiddleware","correct":"from django_htmx.middleware import HtmxMiddleware"},{"note":"Attribute added to the `HttpRequest` object by `HtmxMiddleware`, used to detect htmx requests and access htmx-specific headers (e.g., `request.htmx.boosted`, `request.htmx.current_url_abs_path`).","symbol":"request.htmx","correct":"if request.htmx: ..."},{"note":"Django template tag to include the `django-htmx` extension JavaScript, which provides debug error handling and other features.","symbol":"django_htmx_script","correct":"{% load django_htmx %} {% django_htmx_script %}"},{"note":"Custom Django `HttpResponse` class for triggering client-side redirects via the `HX-Redirect` header.","symbol":"HttpResponseClientRedirect","correct":"from django_htmx.http import HttpResponseClientRedirect"},{"note":"Custom Django `HttpResponse` class for stopping htmx polling requests via the HTTP status code 286.","symbol":"HttpResponseStopPolling","correct":"from django_htmx.http import HttpResponseStopPolling"}],"quickstart":{"code":"import os\nfrom django.shortcuts import render\nfrom django.http import HttpResponse\n\n# settings.py additions\n# INSTALLED_APPS = [\n#     ...,\n#     'django_htmx',\n# ]\n# MIDDLEWARE = [\n#     ...,\n#     'django_htmx.middleware.HtmxMiddleware',\n# ]\n\ndef my_view(request):\n    if request.htmx:\n        # This branch handles HTMX requests\n        return HttpResponse(\"<div>Updated content from HTMX!</div>\")\n    else:\n        # This branch handles initial page load or regular requests\n        context = {'initial_message': 'Click the button below to update!'}\n        return render(request, 'my_template.html', context)\n\n# my_template.html (within your templates directory, inheriting a base.html)\n# Assuming base.html includes the htmx.org script and {% django_htmx_script %}\n# and has <body hx-headers='{\"x-csrftoken\": \"{{ csrf_token }}\"}'>\n#\n# {% load django_htmx %}\n# <!DOCTYPE html>\n# <html lang=\"en\">\n# <head>\n#     <meta charset=\"UTF-8\">\n#     <title>Django HTMX Demo</title>\n#     <script src=\"https://unpkg.com/htmx.org@1.9.10\"></script> <!-- or self-host -->\n#     {% django_htmx_script %}\n# </head>\n# <body hx-headers='{\"x-csrftoken\": \"{{ csrf_token }}\"}'>\n#     <div id=\"content\">{{ initial_message }}</div>\n#     <button hx-get=\"/my-htmx-view/\" hx-target=\"#content\" hx-swap=\"innerHTML\">Load HTMX Content</button>\n# </body>\n# </html>\n\n# urls.py addition (example)\n# from django.urls import path\n# from . import views\n#\n# urlpatterns = [\n#     path('my-htmx-view/', views.my_view, name='my_htmx_view'),\n# ]","lang":"python","description":"This quickstart demonstrates how to set up `django-htmx` and create a basic view that responds differently to HTMX requests. It includes necessary `settings.py` configurations, an example view using `request.htmx`, and a corresponding HTML template snippet. Remember to include the `htmx.org` JavaScript library (e.g., via CDN) and configure CSRF token handling for POST requests."},"warnings":[{"fix":"Add `hx-headers='{\"x-csrftoken\": \"{{ csrf_token }}\"}'` to your `<body>` tag or specific elements, or include a custom JavaScript to add the header to all htmx requests.","message":"CSRF Token Handling for POST requests: HTMX requests do not automatically send Django's CSRF token, which is required for POST, PUT, and DELETE requests. Failure to include it will result in 403 Forbidden errors.","severity":"gotcha","affected_versions":"All versions (Django CSRF dependent)"},{"fix":"Include `htmx.org` via a CDN (`<script src=\"https://unpkg.com/htmx.org@latest\"></script>`) or by downloading and serving it as a static file in your Django project.","message":"HTMX.org JavaScript Library is Separate: `django-htmx` provides Python utilities and template tags to *include* its own extension script, but it does NOT bundle or serve the core `htmx.org` JavaScript library itself. You must explicitly include `htmx.org` in your templates.","severity":"gotcha","affected_versions":"All versions since 1.0.0"},{"fix":"Always include `'django_htmx.middleware.HtmxMiddleware'` in your `MIDDLEWARE` list in `settings.py` for full functionality.","message":"`HtmxMiddleware` is practically essential: While technically optional, most of the core features like `request.htmx` (used to detect htmx requests and access htmx-specific headers) rely on `HtmxMiddleware` being added to your `MIDDLEWARE` setting.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Use `@vary_on_headers('HX-Request')` decorator or manually set `response['Vary'] = 'HX-Request'` in your views that differentiate content based on `request.htmx`.","message":"Vary Headers for HTTP Caching: If your Django views render different HTML content for HTMX requests versus standard browser requests (using `if request.htmx:`), you must add `HX-Request` to the `Vary` header for proper HTTP caching behavior.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Update your templates to directly include `htmx.org` (as mentioned above) and use the current `{% django_htmx_script %}`. Refactor views to use `request.htmx` directly instead of `HTMXViewMixin`.","message":"Removal of old template tags and mixins in 1.0.0: `{% htmx_script %}` (for htmx.org), `HTMXViewMixin`, `{% htmx_include %}`, and `{% htmx_attrs %}` were removed in `django-htmx` version 1.0.0. This was a significant breaking change for users upgrading from pre-1.0.0 versions.","severity":"breaking","affected_versions":"< 1.0.0 to >= 1.0.0"},{"fix":"Consult the `htmx.org` migration guide (e.g., for `htmx.org` 2.0 to 4.0) and thoroughly test your application when upgrading the client-side `htmx.org` library to major versions. Pay attention to changes in the extension API.","message":"Potential breaking changes in `htmx.org` 4.0+: While `django-htmx` is separate, the underlying `htmx.org` library is releasing major versions (e.g., 4.0), which may introduce breaking changes to its core API, extension system, or event handling, potentially impacting custom JavaScript or advanced integrations.","severity":"breaking","affected_versions":"Dependent on htmx.org >= 4.0"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}