-
-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle redirects when htmx == True #91
Comments
This is my concern too. A server redirect isn't necessarily a call for an HTMX redirect... Ideally you'd instead update your "if not logged in then redirect" code to generate the correct response for htmx immediately, rather than modifying it after the fact. Of course that's not always easy when you use e.g. I think we should let this one sit for a little, to think about it. I also hadn't thought about not-logged-in requests so I will look at working with them in my project. |
Some more food for thought: I just did a quick search in the htmx source, and it looks as if 3xx status codes are ignored.
We are using @login_required in this case, a specialised version of that might be a solution. But I'm not sure if it is the right one. |
I'm also working on a project where the majority requests require authentication. For the time being we simply customized django's LoginView class AccountLoginView(LoginView):
template_name = "accounts/login.html"
def get(self, request, *args, **kwargs):
"""
Triggers client-side redirect for htmx requests redirected to the login page.
- Particularly useful when a user's session has expired but their client
is polling for a resource needing authentication.
"""
if request.htmx and REDIRECT_FIELD_NAME in request.GET:
return HttpResponseClientRedirect(settings.LOGIN_URL)
return super().get(request, *args, **kwargs) Anyways, has there been any more ideas or thought given to adding this functionality to django-htmx? |
I was thinking, would it be worth it to add this as a decorator? I think this use case extends beyond just login (although that's exactly what brought me here 😅) and could be applied selectively vs being run on all requests via middleware like so: def htmx_redirect(func):
def wrapper(self, request, *args, **kwargs):
response = func(self, request, *args, **kwargs)
if request.htmx and isinstance(response, HttpResponseRedirect):
response['HX-Redirect'] = response['Location']
response.status_code = 204
return response
return wrapper |
Click to expand!def htmx_guard_redirect(redirect_name):
"""
Decorator for guarding HTMX-only function views.
If a request comes in to this endpoint that did not originate from HTMX,
respond with a redirect to the requested endpoint.
Usage:
@htmx_guard_redirect("homepage")
def htmx_only_function(request):
...
Takes an optional `test` boolean that bypasses the redirect.
"""
# https://stackoverflow.com/a/9030358
def _method_wrapper(view_method: Callable) -> Callable:
def _arguments_wrapper(
request: Request, *args, **kwargs
) -> HttpResponseRedirect | Callable:
testing = False
if "test" in kwargs.keys():
testing = kwargs.pop("test")
if not request.htmx and not testing:
return HttpResponseRedirect(reverse(redirect_name))
return view_method(request, *args, **kwargs)
return _arguments_wrapper
return _method_wrapper |
This blog post highlights that returning a HTTP 303 status code might sometimes be particularly convenient with HTMX. Indeed, when you perform actions using HTTP methods like PUT / DELETE / PATCH and you want to redirect after the action is completed, using a 303 response ensures that the subsequent request after the redirection will be done using a GET method. I'd just like to emphasize this point, which hasn't yet been mentioned, although it seems to be closely related to the potential new functionality being discussed here. |
Personally, I'm in favour of having such a mechanism in django-htmx. I've just started learning HTMX, having already worked with Django for several years, and I was surprised not to find a solution in the documentation for managing authenticated routes like in classic Django. In addition, since it's a middleware, it lets the user choose whether or not to activate it depending on whether it can work for their project. Finally, it would allow many Django components to work directly without having to override some methods that are sometimes not designed to be easily overridden, such as In any case, thanks for the library, it works like a charm! |
In a project I'm working on we logout priviliged users after some time. This has the downside of returning a
HttpResponseRedirect
when issuing a htmx request, ie. when a user tries to use an already open browser tab the next day.For now we have solved the problem by writing the following middleware:
This tells htmx to do a complete reload of the page leading to a redirect to the login page.
I think that the above approach might be a bit too generic - do we want to issue a redirect every time? For now it serves us fine since we are evaluating htmx in a small portion of our project.
The question is whether django-htmx should offer something similar?
The text was updated successfully, but these errors were encountered: