-
Use HTTP 303 for redirections.
-
Setup django-htmx to see Django error response pages despite Ajax.
-
Trigger back client side events from the backend using the
Hx-Trigger
header.
Yes, it does.
You can drop a script tag and start using HTMX with any Django website and call it a day. That’s one of the benefits of the tech. Like all techs though, the more you use it, the more you get comfy with it and demand more of it.
If you decide that you too would like to give a try to HTMX with real-world use cases, then chances are you will eventually reach this point as well.
So let’s share.
Long ago when XML was the future, I was hunting mammoths with notepad++, painting in caves with PHP or cooking with fastcgi; and we used forms to do pretty much every interaction with the user.
The typical workflow is the following:
-
Setup validation in the end point.
-
If it’s a POST request and the data is valid, perform the user requested operation and redirect (to avoid F5 side effects).
-
If not, setup user feedback, and display the form in HTML.
Doing that with HTMX on top is a good way to start with something dumb and improve it by sparkling it with a bit of magical automatic AJAX. Later on, you’ll likely want to trigger requests on more granular widgets and events, but as a starting point, it’s great.
However, Django canonical way of sending back redirection responses is the redirect function, with a signature looking like this:
redirect(to, *args, permanent=False, **kwargs)
You set permanent
to False
or True
depending on whether you want the HTTP status code to be 302 (Found) or 301 (Permanent redirect).
However, what you sometimes want with HTMX is the status code 303 (See other), because the HTTP specs specifies that the client should use the same HTTP verb to follow the redirection than the original response. And while with a regular browser this didn’t matter since you could only do POST and GET, with HTMX you suddenly can do POST, GET, PUT, DELETE and PATCH from anything. It suddenly is quite convenient to be able to use 303.
Fortunately, you can create an HTTP response manually in Django. When I need this kind of redirection, I use the following snippet:
def see_other(to, *args, **kwargs): response = HttpResponse(content="See other", status=303) response["Location"] = resolve_url(to, *args, **kwargs) return respons