Django: How to add next to manual login redirect?

Viewed 161

I have a view:

def create_something(request):
    ...

I want to redirect to login if a person isn't logged in. Normally I'd use:

@login_required
def create_something(request):
    ...

but ... I want to add a message before the redirect.

I wanted to do it like this:

def create_something(request):
    if not request.user.is_authenticated:
        messages.info(request, 'You must be logged in to create a thing .')
        return redirect('login')
    ...

However, that doesn't include a ?next in the url to go back to the page I was going to.

So my question is:

How would you manually redirect back to the login page WITH a manually added ?next query?

2 Answers

We can look at the source code [GitHub] of the @user_passes_test decorator [Django-doc] and determine how such redirect is done.

In the source code we see:

# ⋮
path = request.get_full_path()
from django.contrib.auth.views import redirect_to_login
return redirect_to_login(path, resolved_login_url, redirect_field_name)

We can thus mimic this behaviour with:

from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.views import redirect_to_login
from django.urls import reverse

def create_something(request):
    if not request.user.is_authenticated:
        messages.info(request, 'You must be logged in to create a thing �.')
        path = request.get_full_path()
        return redirect_to_login(path, reverse('login'))
    # …

Here the .redirect_to_login(…) function [Django-doc] will thus produce a redirect where the querystring will contain a key next=… where next is associated with the path.

You should use path = request.build_absolute_uri() in case the schema or hostname.

Just add the below decorator to your function:

 @login_required(login_url='/console/login')

The 'console/login' is the url path you want to redirect to. Alternatively, you can add the url to your settings.py file.

 LOGIN_URL = 'url'
Related