Registry / web-framework / django-htmx

django-htmx

JSON →
library1.29.0pypypi✓ verified 26d ago

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.

pip install django-htmx
INSTALL
IMPORT
SIG · DJANGO-HTMX
D
django-htmx
web-frameworkpythonv1.29.0
Install
3.5s avg
Import
725ms
Disk
66MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.9–3.13
musl
3.9–3.13
Install & Compatibility
Where this runs
tested against v1.29.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.754s · 67.2MB
glibc
py 3.10–3.95 runs
installs and imports cleanly · install 3.5s · import 0.696s · 68MB
66MB installed
● package 66MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

HtmxMiddleware
✓ from django_htmx.middleware import HtmxMiddleware
Required to enable `request.htmx` and other htmx-specific request processing.
request.htmx
✓ if request.htmx: ...
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`).
django_htmx_script
✓ {% load django_htmx %} {% django_htmx_script %}
Django template tag to include the `django-htmx` extension JavaScript, which provides debug error handling and other features.
HttpResponseClientRedirect
✓ from django_htmx.http import HttpResponseClientRedirect
Custom Django `HttpResponse` class for triggering client-side redirects via the `HX-Redirect` header.
HttpResponseStopPolling
✓ from django_htmx.http import HttpResponseStopPolling
Custom Django `HttpResponse` class for stopping htmx polling requests via the HTTP status code 286.

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.

import os from django.shortcuts import render from django.http import HttpResponse # settings.py additions # INSTALLED_APPS = [ # ..., # 'django_htmx', # ] # MIDDLEWARE = [ # ..., # 'django_htmx.middleware.HtmxMiddleware', # ] def my_view(request): if request.htmx: # This branch handles HTMX requests return HttpResponse("<div>Updated content from HTMX!</div>") else: # This branch handles initial page load or regular requests context = {'initial_message': 'Click the button below to update!'} return render(request, 'my_template.html', context) # my_template.html (within your templates directory, inheriting a base.html) # Assuming base.html includes the htmx.org script and {% django_htmx_script %} # and has <body hx-headers='{"x-csrftoken": "{{ csrf_token }}"}'> # # {% load django_htmx %} # <!DOCTYPE html> # <html lang="en"> # <head> # <meta charset="UTF-8"> # <title>Django HTMX Demo</title> # <script src="https://unpkg.com/htmx.org@1.9.10"></script> <!-- or self-host --> # {% django_htmx_script %} # </head> # <body hx-headers='{"x-csrftoken": "{{ csrf_token }}"}'> # <div id="content">{{ initial_message }}</div> # <button hx-get="/my-htmx-view/" hx-target="#content" hx-swap="innerHTML">Load HTMX Content</button> # </body> # </html> # urls.py addition (example) # from django.urls import path # from . import views # # urlpatterns = [ # path('my-htmx-view/', views.my_view, name='my_htmx_view'), # ]
Debug
Known issues
gotchaCSRF 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.
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.
affects: All versions (Django CSRF dependent)
gotchaHTMX.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.
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.
affects: All versions since 1.0.0
gotcha`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.
fix
Always include `'django_htmx.middleware.HtmxMiddleware'` in your `MIDDLEWARE` list in `settings.py` for full functionality.
affects: All versions
gotchaVary 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.
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`.
affects: All versions
breakingRemoval 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.
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`.
affects: < 1.0.0 to >= 1.0.0
breakingPotential 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.
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.
affects: Dependent on htmx.org >= 4.0
Errors
Common errors & fixes
AttributeError: 'WSGIRequest' object has no attribute 'htmx'
This error occurs when `django-htmx`'s middleware, `HtmxMiddleware`, is not correctly added to your Django project's `MIDDLEWARE` setting, preventing the `request.htmx` attribute from being attached to the request object.
fix
Ensure 'django_htmx.middleware.HtmxMiddleware' is included in your `settings.py` file, preferably after Django's `SessionMiddleware` and `CommonMiddleware`:
```python
# settings.py

INSTALLED_APPS = [
    # ...
    "django_htmx",
]

MIDDLEWARE = [
    # ...
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django_htmx.middleware.HtmxMiddleware",
    # ...
]
```
Forbidden (CSRF token missing or incorrect)
This 403 Forbidden error typically happens when making POST requests with htmx without correctly including Django's CSRF token in the request headers, as Django's `CsrfViewMiddleware` rejects requests lacking a valid token.
fix
Add the `hx-headers` attribute to your `<body>` tag (or a parent element) in your base template to automatically include the CSRF token with all htmx requests:
```html
<!-- base.html -->
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
    <!-- Your content -->
</body>
```
django.urls.exceptions.NoReverseMatch
This error occurs when Django's `reverse()` function or the `{% url %}` template tag cannot find a matching URL pattern for the given name and arguments, often due to a typo in the URL name, missing arguments, or an unincluded URL configuration.
fix
Verify that the URL name used in `{% url 'your_url_name' %}` (or `reverse('your_url_name')`) exactly matches a `name` defined in your `urls.py`. If the URL pattern expects arguments, ensure they are correctly passed:
```python
# urls.py
path('items/<int:item_id>/', views.item_detail, name='item_detail'),

# template.html
<a href="{% url 'item_detail' item.id %}">View Item</a>
```
KeyError at /
A `KeyError` typically occurs in Django views when attempting to access a dictionary key that does not exist in the context, request data, or a dictionary derived from a JSON response, often happening during partial updates or when expected data is missing from an HTMX-triggered request.
fix
Before accessing dictionary keys, always check for their existence using `dict.get()` with a default value, or by using `if key in dict:` to prevent the error. For example, when parsing request data:
```python
# views.py
def my_view(request):
    if request.htmx and request.method == 'POST':
        data = request.POST
        item_name = data.get('item_name', 'Default Name') # Use .get() method
        # ... or check existence
        if 'item_id' in data:
            item_id = data['item_id']
        else:
            item_id = None
    # ...
```
Upgrade
Version history
1.29.0latest on PyPI · released Aug 5, 2026
Audit
Dependencies
DjangorequiredCore framework dependency. Supports Django 4.2 to 6.0.
htmx.org (client-side JS library)requiredThe JavaScript library that django-htmx extends. Must be included in templates via CDN or static files.
Agent activity
20 hits · last 30 days
node
16
Amazon
1
Resources
django-htmx — pip install django-htmx · libregistry