:orphan: :py:mod:`utils` =========================== Functions ~~~~~~~~~ .. autoapisummary:: hx_requests.utils.parse_model_ref hx_requests.utils.resolve_model_ref hx_requests.utils.sign_hx_payload hx_requests.utils.unsign_hx_payload hx_requests.utils.get_hx_payload hx_requests.utils.get_hx_request_name hx_requests.utils.is_hx_request :py:mod:`parse_model_ref` ------------------------- .. py:function:: parse_model_ref(value) If ``value`` is a serialized model-instance reference (``model_instance______``), return ``(app_label, model_name, pk)``; otherwise return ``None``. Uses a length-based slice (not ``str.replace``) so a pk/label that happens to contain the prefix can't be mangled. :py:mod:`resolve_model_ref` --------------------------- .. py:function:: resolve_model_ref(app_label, model_name, pk, queryset=None) Fetch a model instance from a parsed reference. Resolution goes through ``queryset`` when one is supplied (the object-scoping seam -- see ``BaseHxRequest.get_queryset``); otherwise it falls back to the model's ``_default_manager``. The default manager (not ``_base_manager``) is deliberate: any scoping expressed on the default manager is respected automatically, so an object the default manager hides cannot be resolved unless a handler explicitly widens the queryset. Raises the model's ``DoesNotExist`` when the pk is absent from the resolved queryset. :py:mod:`sign_hx_payload` ------------------------- .. py:function:: sign_hx_payload(hx_request_name, obj=None, bind_path=None, **kwargs) Pack everything the template tag controls -- the handler name, the object, and the extra kwargs -- into a single HMAC-signed token. The client can read the token (it is base64-encoded JSON) but cannot forge it without ``SECRET_KEY``, which closes the object/kwarg/name tampering vectors. When ``bind_path`` is given, it is packed into the token too, binding the token to that URL path (see :func:`get_url` and ``bind_to_path``). :py:mod:`unsign_hx_payload` --------------------------- .. py:function:: unsign_hx_payload(token) Verify and unpack a signed token. Raises ``signing.BadSignature`` (a base class covering tampered/truncated/hand-crafted tokens) on any failure. :py:mod:`get_hx_payload` ------------------------ .. py:function:: get_hx_payload(request) Return the *verified* contents of the signed ``hx`` token on ``request`` as ``{"name": ..., "object": ..., "kwargs": ...}``, or ``None`` if the request carries no token or the signature is invalid. This is the supported way for view code to introspect an inbound hx-requests request (detect it, read its name/object/kwargs) *without* going through ``HtmxViewMixin`` dispatch. The ``object`` and ``kwargs`` values are still in serialized form -- pass them through :func:`deserialize` / :func:`deserialize_kwargs` to get live values. :py:mod:`get_hx_request_name` ----------------------------- .. py:function:: get_hx_request_name(request) Return the :code:`HxRequest` name from the signed ``hx`` token, or ``None`` if the request isn't a (valid) hx-requests request. Replaces reading ``request.GET["hx_request_name"]`` directly, which no longer exists on the query string now that routing data is signed. :py:mod:`is_hx_request` ----------------------- .. py:function:: is_hx_request(request) Return ``True`` if ``request`` is an hx-requests request -- i.e. it carries a valid signed ``hx`` token bound for a registered handler. This is distinct from :func:`is_htmx_request`, which only checks the ``HX-Request`` header (*any* htmx request). Use it to tell a plain htmx request (sort / filter / paginate) apart from one routed to an :code:`HxRequest`:: if is_htmx_request(request) and not is_hx_request(request): ... # plain htmx -- let the underlying view handle it