0

In my django project I use the LoginView from contrib.auth to let users login. Currently a user is redirected to the mainpage, when he successfully logged in. But since I'm adding some features that require authentication, I'd like to redirect unauthenticated users to the login page and then back to the page they originally requested once they are logged in.

In the internet I found several solutions, but none of them works for me, either because they are outdated or because they use custom login methods. Although I could implement my own login method, I would like to stick to the built in functionality if possible.

Here is my code so far:

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import include
from django.contrib.auth import views as auth_views

urlpatterns = [
    path('', include('Mainpage.urls')),
    path('index/', include('Mainpage.urls'), name='index'),
    path('login/', auth_views.LoginView.as_view(template_name='login/login.html', redirect_field_name='next'),
         name='login'),
    path('test/', include('test.urls'), name='test'),
]

login-template

{% extends "base.html" %}

{% block content %}
{% if not user.is_authenticated %}
<h2>Logge dich in deinen Account ein:</h2>
  {% if form.errors %}
    <p style="color: red">Benutzername und/oder Passwort war falsch. Bitte versuche es erneut.</p>
  {% endif %}
  <form method="post">
    {% csrf_token %}
    {% if request.POST.next %}
      <input type="hidden" name="next" value="{{ request.POST.next }}" />
    {% else %}
      <input type="hidden" name="next" value="{% url 'index' %}" />
    {% endif %}
    {% for field in form %}
      <p>
        {{ field.label_tag }}<br>
        {{ field }}<br>
        {% for error in field.errors %}
          <p style="color: red">{{ error }}</p>
        {% endfor %}
        {% if field.help_text %}
          <p><small style="color: grey">{{ field.help_text }}</small></p>
        {% endif %}
      </p>
    {% endfor %}
    <button type="submit">Log in</button>
  </form>
{% else %}
<p>Du bist eingeloggt.</p>
{% endif %}
{% endblock %}

What do I have to change, so that a user is redirected to /test, if the login page is requested as https://example.com/login?next=test? I thould it would work, to get the next parameter from the request.POST dict and then set it as the redirect_field of LoginView, but it always enters the else-clause. Is this possible with the built-in LoginView or do I have to write my own method?

EDIT: Django - after login, redirect user to his custom page --> mysite.com/username does not solve this question, since I'm not trying to redirect based upon data from a model but from a parameter in the URI.

AracKnight
  • 357
  • 5
  • 18
  • Specifically: https://stackoverflow.com/a/45201405/1305461 – felipe Jul 11 '20 at 01:07
  • No, this doesn't answer my question. It might be possible to achieve a workaround with this method, but I still face the same problem of how to get the next parameter /login was called with – AracKnight Jul 11 '20 at 01:30

2 Answers2

1

So basically what you would want to do is go into test.urls.py and import the login_required decorator.

from django.urls import path
from django.contrib.auth.decorators import login_required

from . import views

urlpatterns = [
    path('test/', login_required(views.test), name='testpage'),
]

Basically what this just did is it added a authentication requirement to that view. So in your test.views.py, the "test" view is restricted to logged out Users. Anyone who isn't logged in is redirected to the login page and once they log in they are sent to their original destination.

LOGIN_URL = 'name of login page url'

You also need to put this into your settings.py file. This is the page unauthenticated users are redirected to login so they can access that page.

darkstar
  • 829
  • 11
  • 23
  • This does not work. It redirects from test to the login page, but after the login it redirects me to /index, not to test, from where I came from. – AracKnight Jul 11 '20 at 01:29
  • Are you using function based views or class based views? – darkstar Jul 11 '20 at 01:33
  • Actually I'm using function based views. This LoginView.as_view is an exception, cause I found no ther built in function, that was not class based. – AracKnight Jul 11 '20 at 01:36
  • yeah so that should be working perfectly. maybe try and import the login decorator above the view itself – darkstar Jul 11 '20 at 01:53
1

Try <input type="hidden" name="next" value="{{ next }}" /> before submitting the login form. The next parameter has to be a URL. If this parameter is given, the Django login view will redirect the user to the given URL after a successful login. I hope this helps.

Sheraram_Prajapat
  • 589
  • 1
  • 9
  • 27