Middleware¶
- class django_htmx.middleware.HtmxMiddleware[source]¶
This middleware attaches
request.htmx
, an instance ofHtmxDetails
(below). Your views, and any following middleware, can userequest.htmx
to switch behaviour for requests from htmx. The middleware supports both sync and async modes.See it action in the “Middleware Tester” section of the example project.
Set the
Vary
header for cacheable responsesIf you set HTTP caching headers, ensure any views that switch content with
request.htmx
attributes add the appropriate htmx headers to theVary
header, per Django’s documentation section UsingVary
headers. For example:from django.shortcuts import render from django.views.decorators.cache import cache_control from django.views.decorators.vary import vary_on_headers @cache_control(max_age=300) @vary_on_headers("HX-Request") def my_view(request): if request.htmx: template_name = "partial.html" else: template_name = "complete.html" return render(request, template_name, ...)
Hint
If you are type-checking your Django project, declare
request.htmx
as below in any customHttpRequest
classes, per the pattern in django-stubs.from django.http import HttpRequest as HttpRequestBase from django_htmx.middleware import HtmxDetails class HttpRequest(HttpRequestBase): htmx: HtmxDetails
- class django_htmx.middleware.HtmxDetails[source]¶
This class provides shortcuts for reading the htmx-specific request headers.
- __bool__()[source]¶
True
if the request was made with htmx, otherwiseFalse
. Detected by checking if theHX-Request
header equalstrue
.This method allows you to change content for requests made with htmx:
from django.shortcuts import render def my_view(request): if request.htmx: template_name = "partial.html" else: template_name = "complete.html" return render(request, template_name, ...)
- Return type:
bool
- boosted: bool¶
True
if the request came from an element with thehx-boost
attribute. Detected by checking if theHX-Boosted
header equalstrue
.You can use this attribute to change behaviour for boosted requests:
def my_view(request): if request.htmx.boosted: # do something special ... return render(...)
- current_url: str | None¶
The current URL in the browser that htmx made this request from, or
None
for non-htmx requests. Based on theHX-Current-URL
header.
- current_url_abs_path: str | None¶
The absolute-path form of
current_url
, that is the URL without scheme or netloc, orNone
for non-htmx requests.This value will also be
None
if the scheme and netloc do not match the request. This could happen if the request is cross-origin, or if Django is not configured correctly.For example:
>>> request.htmx.current_url 'https://example.com/dashboard/?year=2022' >>> # assuming request.scheme and request.get_host() match: >>> request.htmx.current_url_abs_path '/dashboard/?year=2022'
This is useful for redirects:
if not sudo_mode_active(request): next_url = request.htmx.current_url_abs_path or "" return HttpResponseClientRedirect(f"/activate-sudo/?next={next_url}")
- history_restore_request: bool¶
True
if the request is for history restoration after a miss in the local history cache. Detected by checking if theHX-History-Restore-Request
header equalstrue
.
- target: str | None¶
The
id
of the target element if it exists, orNone
. Based on theHX-Target
header.
- trigger: str | None¶
The
id
of the triggered element if it exists, orNone
. Based on theHX-Trigger
header.
- trigger_name: str | None¶
The
name
of the triggered element if it exists, orNone
. Based on theHX-Trigger-Name
header.
- triggering_event: Any | None¶
The deserialized JSON representation of the event that triggered the request if it exists, or
None
. This header is set by the event-header htmx extension, and contains details of the DOM event that triggered the request.