djangodjango-templatesdjango-logindjango-messages

how to use django message framework for @login_required to show message


I am using @login required decorator in my most of views so what I want is to use message in my login page telling user if you want to open that page you have to login first so how I can achieve that I know I cannot achieve that on my views so anyone does that and know how to do please tell me how to achieve that if a user redirected to login because of @login required I want to show message please login to continue

I also looked on some of the same question I am looking for answer which got implemented on all the login required decorator so I don't have to change code everywhere it already got implemented in all of the login required decorator in my whole app

my login view

def my_login(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data["username"]
            password = form.cleaned_data["password"]
            remember_me = form.cleaned_data['remember_me']
            user = authenticate(username=username, password=password)
            if user:
                login(request, user)
                if not remember_me:
                    request.session.set_expiry(0)
                    return redirect('accounts:home')
                else:
                    request.session.set_expiry(1209600)
                    return redirect('accounts:home')
            else:
                return redirect('accounts:login')
        else:
            return redirect('accounts:register')
    else:
        form = LoginForm()
        return render(request, "login.html", {'form': form})

Solution

  • Solution 1:

    In your view, check the query parameter "next", as if the user is redirected to the login view, it would come with the ?next=/whatever in the URL. You can do

    if 'next' in request.GET:
        messages.add_message(request, messages.INFO, 'Hello world.')
    

    Solution 2 (not recommended, this makes it confusing to debug for others):

    Python being a dynamic language, you can hijack the behaviour of login_required with your version.

    in your manage.py and wsgi.py and maybe asgi.py you would need to "monkey patch" the login_required decorator.

    from django.contrib.auth import decorators
    
    def my_login_required(...):
        # you can look at the implementation in the answer by LvanderRee mentioned in the comments
    
    decorators.login_required = my_login_required
    

    Now, because these files will be the first code to execute before Django even starts, this will replace the built-in login_required with your version.