adamchainz / django-htmx

Extensions for using Django with htmx.
https://django-htmx.readthedocs.io/
MIT License
1.66k stars 140 forks source link

Redirect after login #398

Closed Mte90 closed 3 months ago

Mte90 commented 12 months ago

Python Version

3.11

Django Version

4.x

Package Version

1.17.x

Description

So I have this code but the redirect is not working, there is just a replacement in the div on success. I can see that the cookie is not configured for the login with that, but on the django admin it works.

My form:

<form hx-post="{% url 'login_submit' %}" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-target="#result">
                        {% csrf_token %}
                        {% for field in form %}
                        <p>
                            {{ field.label_tag }}
                            {{ field }}
                            {% if field.help_text %}
                                <div class="text-gray-400">{{ field.help_text }}</div>
                            {% endif %}
                        </p>
                        {% endfor %}
                        <button class="px-6 py-2 text-sm text-black bg-orange-200 rounded-lg outline-none hover:bg-orange-200 ring-indigo-300" type="submit">Login</button>
                        <p id="result" class="text-red-400"></p>
                    </form>

My function:

@require_POST
def login_submit(request: HtmxHttpRequest) -> HttpResponse:  # noqa
    form = LoginForm(request.POST)
    if form.is_valid():
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']
        if User.objects.filter(username=username).exists():
            user = authenticate(request, username=username, password=password)
            if user:
                login(request, user)
                return HttpResponseClientRedirect(reverse('index'))
        return HttpResponse(
            'Wrong login data'
        )
    else:
        return HttpResponse(
            mark_safe(form.errors)
        )
brablc commented 10 months ago

It looks as if you were trying to redirect to the same URL on which you are. In this case nothing will happen, unless you add HX-Refresh header to the response. See the htmx.js code:

            var shouldRefresh = hasHeader(xhr, /HX-Refresh:/i) && "true" === xhr.getResponseHeader("HX-Refresh");

            if (hasHeader(xhr, /HX-Redirect:/i)) {
                location.href = xhr.getResponseHeader("HX-Redirect");
                shouldRefresh && location.reload();
                return;
            }

It does not seem you can do this by using django-htmx directly, because HttpResponseClientRedirect and HttpResponseClientRefresh do not seem to be able to be used at the same time.

Mte90 commented 10 months ago

No I am trying to redirect to the homepage in case the login (that is another page) success. The home page already has the decorator for login_required

brablc commented 10 months ago

I would suggest using a browser network panel to see what headers the redirect brings and putting breakpoint to proper place in htmx.js to see whether location.href changes and/or reload is made.

Mte90 commented 10 months ago

Another solution it is more simple as it is the login, when is successful that page automatically should redirect to the home page, so if I do a refresh of the login page when it is successful it should be enough to get the same behavior.

adamchainz commented 3 months ago

Sorry, I cannot provide support on this issue tracker.