Django: Redirect logged in users from login page

Django

Django Problem Overview


I want to set up my site so that if a user hits the /login page and they are already logged in, it will redirect them to the homepage. If they are not logged in then it will display normally. How can I do this since the login code is built into Django?

Django Solutions


Solution 1 - Django

I'm assuming you're currently using the built-in login view, with

(r'^accounts/login/$', 'django.contrib.auth.views.login'),

or something similar in your urls.

You can write your own login view that wraps the default one. It will check if the user is already logged in (through is_authenticated attribute official documentation) and redirect if he is, and use the default view otherwise.

something like:

from django.contrib.auth.views import login

def custom_login(request):
    if request.user.is_authenticated:
        return HttpResponseRedirect(...)
    else:
        return login(request)

and of course change your urls accordingly:

(r'^accounts/login/$', custom_login),

Solution 2 - Django

The Django 1.10 way

For Django 1.10, released in August 2016, a new parameter named redirect_authenticated_user was added to the login() function based view present in django.contrib.auth [1].

Example

Suppose we have a Django application with a file named views.py and another file named urls.py. The urls.py file will contain some Python code like this:

#
# Django 1.10 way
#
from django.contrib.auth import views as auth_views
from . import views as app_views


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', auth_views.login, name='login',
        kwargs={'redirect_authenticated_user': True}),
    url(r'^dashboard/', app_views.Dashboard.as_view(), name='dashboard'),
    url(r'^$', TemplateView.as_view(template_name='index.html'), name='index'),
]

From that file, the relevant part within the urlpatterns variable definition is the following, which uses the already mentioned redirect_authenticated_user parameter with a True value:

    url(r'^login/', auth_views.login, name='login',
        kwargs={'redirect_authenticated_user': True}),

Take note that the default value of the redirect_authenticated_user parameter is False.

The Django 1.11 way

For Django 1.11, released in April 2017, the LoginView class based view superseded the login() function based view [2], which gives you two options to choose from:

  • Use the same Django 1.10 way just described before, which is a positive thing because your current code will continue working fine. If you tell Python interpreter to display warnings, by for example running in a console terminal the command python -Wd manage.py runserver in your Django project directory and then going with a web browser to your login page, you would see in that same console terminal a warning message like this:

> /usr/local/lib/python3.6/site-packages/django/contrib/auth/views.py:54: > RemovedInDjango21Warning: The login() view is superseded by the > class-based LoginView().

  • Use the new Django 1.11 way, which will make your code more modern and compatible with future Django releases. With this option, the example given before will now look like the following one:
Example

We again suppose that we have a Django application with a file named views.py and another file named urls.py. The urls.py file will contain some Python code like this:

#
# Django 1.11 way
#
from django.contrib.auth import views as auth_views
from . import views as app_views


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/',
        auth_views.LoginView.as_view(redirect_authenticated_user=True),
        name='login'),
    url(r'^dashboard/', app_views.Dashboard.as_view(), name='dashboard'),
    url(r'^$', TemplateView.as_view(template_name='index.html'), name='index'),
]

From that file, the relevant part within the urlpatterns variable definition is the following, which again uses the already mentioned redirect_authenticated_user parameter with a True value, but passing it as an argument to the as_view method of the LoginView class:

    url(r'^login/',
        auth_views.LoginView.as_view(redirect_authenticated_user=False),
        name='login'),

Take note that here the default value of the redirect_authenticated_user parameter is also False.

References

Solution 3 - Django

anonymous_required decorator

For class based views

Code:

from django.shortcuts import redirect

def anonymous_required(func):
    def as_view(request, *args, **kwargs):
        redirect_to = kwargs.get('next', settings.LOGIN_REDIRECT_URL )
        if request.user.is_authenticated():
            return redirect(redirect_to)
        response = func(request, *args, **kwargs)
        return response
    return as_view

Usage:

url(r'^/?$',
   anonymous_required(auth_views.login),
),
url(r'^register/?$',
    anonymous_required(RegistrationView.as_view()),
    name='auth.views.register'
),
# Could be used to decorate the dispatch function of the view instead of the url

For view functions

From http://blog.motane.lu/2010/01/06/django-anonymous_required-decorator/

Code:

from django.http import HttpResponseRedirect

def anonymous_required( view_function, redirect_to = None ):
    return AnonymousRequired( view_function, redirect_to )
 
class AnonymousRequired( object ):
    def __init__( self, view_function, redirect_to ):
        if redirect_to is None:
            from django.conf import settings
            redirect_to = settings.LOGIN_REDIRECT_URL
        self.view_function = view_function
        self.redirect_to = redirect_to
 
    def __call__( self, request, *args, **kwargs ):
        if request.user is not None and request.user.is_authenticated():
            return HttpResponseRedirect( self.redirect_to )
        return self.view_function( request, *args, **kwargs )

Usage:

@anonymous_required
def my_view( request ):
    return render_to_response( 'my-view.html' )

Solution 4 - Django

For Django 2.x, in your urls.py:

from django.contrib.auth import views as auth_views
from django.urls import path

urlpatterns = [
    path('login/', auth_views.LoginView.as_view(redirect_authenticated_user=True), name='login'),
]

Solution 5 - Django

Add this decorator above your login view to redirect to /home if a user is already logged in

@user_passes_test(lambda user: not user.username, login_url='/home', redirect_field_name=None)

and don't forget to import the decorator

from django.contrib.auth.decorators import user_passes_test

Solution 6 - Django

Since class based views (CBVs) is on the rise. This approach will help you redirect to another url when accessing view for non authenticated users only.

In my example the sign-up page overriding the dispatch() method.

class Signup(CreateView):
    template_name = 'sign-up.html'

    def dispatch(self, *args, **kwargs):
        if self.request.user.is_authenticated:
            return redirect('path/to/desired/url')
        return super().dispatch(*args, **kwargs)

Cheers!

Solution 7 - Django

https://docs.djangoproject.com/en/3.1/topics/auth/default/#all-authentication-views

Add the redirect route in settings

LOGIN_URL = 'login'

And in the URLs add redirect_authenticated_user=True to LoginView

path('login/', auth_views.LoginView.as_view(template_name='users/login.html',redirect_authenticated_user=True), name='login')

Solution 8 - Django

I know this is a pretty old question, but I'll add my technique in case anyone else needs it:


myproject/myapp/views/misc.py

from django.contrib.auth.views import login as contrib_login, logout as contrib_logout
from django.shortcuts import redirect
from django.conf import settings


def login(request, **kwargs):
    if request.user.is_authenticated():
        return redirect(settings.LOGIN_REDIRECT_URL)
    else:
        return contrib_login(request, **kwargs)

logout = contrib_logout

myproject/myapp/urls.py

from django.conf.urls import patterns, url

urlpatterns = patterns('myapp.views.misc',
    url(r'^login/$', 'login', {'template_name': 'myapp/login.html'}, name='login'),
    url(r'^logout/$', 'logout', {'template_name': 'myapp/logout.html'}, name='logout'),
)
...

Solution 9 - Django

Assuming that you are done setting up built-in Django user authentication (and using decorators), add this in your settings.py:

LOGIN_REDIRECT_URL = '/welcome/'

NOTE: '/welcome/' here is the URL of the homepage. It is up to you what to replace it with.

Solution 10 - Django

All you have to do is set the "root" url to the homepage view. Since the homepage view is already restricted for logged on users, it'll automatically redirect anonymous users to the login page.

Kepp the url as it is. And add something like:

(r'^$', 'my_project.my_app.views.homepage'),

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWill M.View Question on Stackoverflow
Solution 1 - DjangoOfri RavivView Answer on Stackoverflow
Solution 2 - DjangorodolfojcjView Answer on Stackoverflow
Solution 3 - DjangolaffusteView Answer on Stackoverflow
Solution 4 - DjangoQuiqueView Answer on Stackoverflow
Solution 5 - DjangoStephenView Answer on Stackoverflow
Solution 6 - DjangoRoelView Answer on Stackoverflow
Solution 7 - Djangoatufa shireenView Answer on Stackoverflow
Solution 8 - DjangodgelView Answer on Stackoverflow
Solution 9 - DjangoAmazing AngeloView Answer on Stackoverflow
Solution 10 - DjangoLuiz C.View Answer on Stackoverflow