Coverage for utilities/htmx.py: 26%
21 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1from urllib.parse import urlsplit
3from django.http import HttpResponse
4from django.urls import reverse
6__all__ = (
7 'htmx_current_url',
8 'htmx_maybe_redirect_current_page',
9 'htmx_partial',
10)
13def htmx_partial(request):
14 """
15 Determines whether to render partial (versus complete) HTML content
16 in response to an HTMX request, based on the target element.
17 """
18 return request.htmx and not request.htmx.boosted
21def htmx_current_url(request) -> str:
22 """
23 Extracts the current URL from the HTMX-specific headers in the given request object.
25 This function checks for the `HX-Current-URL` header in the request's headers
26 and `HTTP_HX_CURRENT_URL` in the META data of the request. It preferentially
27 chooses the value present in the `HX-Current-URL` header and falls back to the
28 `HTTP_HX_CURRENT_URL` META data if the former is unavailable. If neither value
29 exists, it returns an empty string.
30 """
31 return request.headers.get('HX-Current-URL') or request.META.get('HTTP_HX_CURRENT_URL', '') or ''
34def htmx_maybe_redirect_current_page(
35 request, url_name: str, *, preserve_query: bool = True, status: int = 200
36) -> HttpResponse | None:
37 """
38 Redirects the current page in an HTMX request if conditions are met.
40 This function checks whether a request is an HTMX partial request and if the
41 current URL matches the provided target URL. If the conditions are met, it
42 returns an HTTP response signaling a redirect to the provided or updated target
43 URL. Otherwise, it returns None.
44 """
45 if not htmx_partial(request):
46 return None
48 current = urlsplit(htmx_current_url(request))
49 target_path = reverse(url_name) # will raise NoReverseMatch if misconfigured
51 if current.path.rstrip('/') != target_path.rstrip('/'):
52 return None
54 redirect_to = target_path
55 if preserve_query and current.query:
56 redirect_to = f'{target_path}?{current.query}'
58 resp = HttpResponse(status=status)
59 resp['HX-Redirect'] = redirect_to
60 return resp