Skip to content
Back to top
View this page
Edit this page

# HTTP tools

## Response classes

class django_htmx.http.HttpResponseClientRedirect(redirect_to, *args, **kwargs)

  htmx can trigger a client-side redirect when it receives a response with the `HX-Redirect` header. `HttpResponseClientRedirect` is a subclass of HttpResponseRedirect for triggering such redirects.

  Parameters:

    - redirect_to (str) – The path to redirect to, as per `HttpResponseRedirect`.

    - args (Any) – Other `HTTPResponse` parameters.

    - kwargs (Any) – Other `HTTPResponse` parameters.

  For example:

      from django_htmx.http import HttpResponseClientRedirect

      def sensitive_view(request):
          if not sudo_mode.active(request):
              return HttpResponseClientRedirect("/activate-sudo-mode/")
          ...

class django_htmx.http.HttpResponseClientRefresh

  htmx will trigger a page reload when it receives a response with the `HX-Refresh` header. `HttpResponseClientRefresh` is a custom response class that allows you to send such a response. It takes no arguments, since htmx ignores any content.

  For example:

      from django_htmx.http import HttpResponseClientRefresh

      def partial_table_view(request):
          if page_outdated(request):
              return HttpResponseClientRefresh()
          ...

class django_htmx.http.HttpResponseLocation(redirect_to, *args, source=None, event=None, target=None, swap=None, select=None, values=None, headers=None, **kwargs)

  An HTTP response class for sending the `HX-Location` header. This header makes htmx make a client-side “boosted” request, acting like a client side redirect with a page reload.

  Parameters:

    - redirect_to (str) –

      The path to redirect to, as per `HttpResponseRedirect`.

    - source (str | None) – The source element of the request.

    - event (str | None) – The event that “triggered” the request.

    - target (str | None) – CSS selector to target.

    - swap (SwapMethod | None) – How the response will be swapped into the target.

    - select (str | None) – Select the content that will be swapped from a response.

    - values (dict[str, str] | None) – values to submit with the request.

    - headers (dict[str, str] | None) – headers to submit with the request.

    - args (Any) – Other `HTTPResponse` parameters.

    - kwargs (Any) – Other `HTTPResponse` parameters.

  For example:

      from django_htmx.http import HttpResponseLocation

      def wait_for_completion(request, action_id):
          ...
          if action.completed:
              return HttpResponseLocation(f"/action/{action.id}/completed/")
          ...

class django_htmx.http.HttpResponseStopPolling(*args, **kwargs)

  When using a polling trigger, htmx will stop polling when it encounters a response with the special HTTP status code 286. `HttpResponseStopPolling` is a custom response class with that status code.

  Parameters:

    - args (Any) – Other `HTTPResponse` parameters.

    - kwargs (Any) – Other `HTTPResponse` parameters.

  For example:

      from django_htmx.http import HttpResponseStopPolling

      def my_pollable_view(request):
          if event_finished():
              return HttpResponseStopPolling()
          ...

django_htmx.http.HTMX_STOP_POLLING: int = 286

  A constant for the HTTP status code 286. You can use this instead of `HttpResponseStopPolling` to stop htmx from polling.

  For example, with Django’s render shortcut:

      from django.shortcuts import render
      from django_htmx.http import HTMX_STOP_POLLING

      def my_pollable_view(request):
          if event_finished():
              return render(request, "event-finished.html", status=HTMX_STOP_POLLING)
          ...

## Response modifying functions

django_htmx.http.push_url(response, url)

  Set the `HX-Push-Url` header of `response` and return it. This header makes htmx push the given URL into the browser location history.

  Parameters:

    - response (_HttpResponse) – The response to modify and return.

    - url (str | Literal[False]) – The (relative) URL to push, or `False` to prevent the location history from being updated.

  Return type:

    _HttpResponse

  For example:

      from django_htmx.http import push_url

      def leaf(request, leaf_id):
          ...
          if leaf is None:
              # Directly render branch view
              response = branch(request, branch=leaf.branch)
              return push_url(response, f"/branch/{leaf.branch.id}")
          ...

django_htmx.http.replace_url(response, url)

  Set the `HX-Replace-Url` header of `response` and return it. This header causes htmx to replace the current URL in the browser location history.

  Parameters:

    - response (_HttpResponse) – The response to modify and return.

    - url (str | Literal[False]) – The (relative) URL to replace, or `False` to prevent the location history from being updated.

  Return type:

    _HttpResponse

  For example:

      from django_htmx.http import replace_url

      def dashboard(request):
          ...
          response = render(request, "dashboard.html", ...)
          # Pretend the user was always on the dashboard, rather than wherever
          # they were on before.
          return replace_url(response, "/dashboard/")

django_htmx.http.reswap(response, method)

  Set the `HX-Reswap` header of `response` and return it. This header overrides the swap method that htmx will use.

  Parameters:

    - response (_HttpResponse) – The response to modify and return.

    - method (Literal['innerHTML', 'outerHTML', 'beforebegin', 'afterbegin', 'beforeend', 'afterend', 'delete', 'none']) – The swap method.

  Return type:

    _HttpResponse

  For example:

      from django.shortcuts import render
      from django_htmx.http import reswap

      def employee_table_row(request):
          ...
          response = render(...)
          if employee.is_boss:
              reswap(response, "afterbegin")
          return response

django_htmx.http.retarget(response, target)

  Set the `HX-Retarget` header of `response` and return it. This header overrides the element that htmx will swap content into.

  Parameters:

    - response (_HttpResponse) – The response to modify and return.

    - target (str) – CSS selector to target.

  Return type:

    _HttpResponse

  For example:

      from django.shortcuts import render
      from django.views.decorators.http import require_POST
      from django_htmx.http import retarget

      @require_POST
      def add_widget(request):
          ...

          if form.is_valid():
              # Rerender the whole table on success
              response = render(request, "widget-table.html", ...)
              return retarget(response, "#widgets")

          # Render just inline table row on failure
          return render(request, "widget-table-row.html", ...)

django_htmx.http.reselect(response, selector)

  Set the `HX-Reselect` header of `response` and return it. This header overrides the selection of the response that htmx will swap into the target.

  Parameters:

    - response (_HttpResponse) – The response to modify and return.

    - selectori – CSS selector of what to select.

    - selector (str)

  Return type:

    _HttpResponse

django_htmx.http.trigger_client_event(response, name, params=None, *, after='receive', encoder=<class 'django.core.serializers.json.DjangoJSONEncoder'>)

  Modify one of the `HX-Trigger` headers of `response` and return it. These headers make htmx trigger client-side events.

  Calling `trigger_client_event` multiple times for the same `response` and `after` will update the appropriate header, preserving existing event specifications.

  Parameters:

    - response (_HttpResponse) – The response to modify and return.

    - name (str) – The name of the event to trigger.

    - params (dict[str, Any] | None) – Optional JSON-compatible parameters for the event.

    - after (Literal['receive', 'settle', 'swap']) –

      Which `HX-Trigger` header to modify:

      - `"receive"`, the default, maps to `HX-Trigger`

      - `"settle"` maps to `HX-Trigger-After-Settle`

      - `"swap"` maps to `HX-Trigger-After-Swap`

    - encoder (type[JSONEncoder]) –

      The `JSONEncoder` class used to generate the JSON. Defaults to `DjangoJSONEncoder` for its extended data type support.

  Return type:

    _HttpResponse

  For example:

      from django.shortcuts import render
      from django_htmx.http import trigger_client_event

      def end_of_long_process(request):
          response = render(request, "end-of-long-process.html")
          return trigger_client_event(
              response,
              "showConfetti",
              {"colours": ["purple", "red", "pink"]},
              after="swap",
          )

## View decorators

django_htmx.http.ptag(ptag_func)

  Decorator to support the polling tags protocol of the `hx-ptag` extension, available for htmx 4 only. Polling tags let views skip re-rendering, and htmx skip swapping, when polled content hasn’t changed, like a lightweight version of Django’s conditional view processing. The API mirrors Django’s `etag` decorator.

  Parameters:

    ptag_func (Callable[[...], str | None]) – A callable to compute the polling tag for the requested content, passed the same parameters as the view itself. It should return the tag as a string — an opaque value representing the current content, such as a hash or updated timestamp — or `None` if the protocol shouldn’t apply.

  Return type:

    Callable[[_View], _View]

  The decorator compares the computed tag with the `HX-PTag` request header, sent by the extension with the value from the previous response. If they match, the decorator returns a 304 (Not Modified) response without calling the view, and htmx skips the swap. Otherwise, it calls the view and adds the `HX-PTag` header to the response, if the header isn’t already set. Like Django’s `condition` decorator, this behaviour only applies to safe request methods, GET and HEAD.

  Both synchronous and asynchronous view functions are supported.

  For example:

      from django.db.models import Max
      from django.shortcuts import render
      from django_htmx.http import ptag

      def latest_news_ptag(request):
          return str(News.objects.aggregate(latest=Max("updated_at"))["latest"])

      @ptag(latest_news_ptag)
      def news_items(request):
          news = News.objects.order_by("-updated_at")[:10]
          return render(request, "news-items.html", {"news": news})