Search code examples
djangohtmx

How to handle redirect for login_required in htmx partial view?


I have two views.

class IndexView(TemplateView):
    template_name = 'index.html'

@require_POST
@login_required
def partial_view(request):
    return render(request, 'partials/stuff.html')

I want the index page to be "public" but if user takes action (which triggers partial view), they should be redirected to LOGIN_URL, if not logged in.

The problem is that my partial view will return the entire LOGIN_URL page. So there's a page within a page now.

Is it possible to redirect the "parent" page when using partial views?


Solution

  • I didn't manage to make "post-login redirection" work but my solution is good enough for my needs.

    from django.contrib.auth import REDIRECT_FIELD_NAME
    from django.conf import settings
    from django.contrib.auth.decorators import login_required as django_login_required
    from django.http import HttpResponse
    from functools import wraps
    
    from django.shortcuts import resolve_url
    
    
    def login_required(function=None, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
        @wraps(function)
        def wrapper(request, *args, **kwargs):
            if not request.user.is_authenticated and request.htmx:
                resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
                return HttpResponse(status=204, headers={'HX-Redirect': resolved_login_url})
            return django_login_required(
                function=function,
                login_url=login_url,
                redirect_field_name=redirect_field_name
            )(request, *args, **kwargs)
        return wrapper