Django message framework and login_required

django messages
custom login_required decorator django
django user model
django messages redirect
django login required
django usercreationform
django authentication
how to display error message in django

I'm using the Django Message Framework to show messages to users as well as the @login_required decorator on one of my views. So if a user tries to access a certain view without being logged in, they get kicked to the login page. How would I go about adding an error message to the login page saying "In order to do ... you must be logged in". I can't add it in the view like you normally would because the non-logged in user would never get to there.

There's not any obvious way. The only thing that springs to mind is to write your own version of the decorator that puts a message into the session before redirecting, then get the login template to display the message from the session.

You'd need to use the code in django.contrib.auth.decorators, in particular the user_passes_test function - the bit to add the message would have to go before return HttpResponseRedirect.

Django message framework and login_required - django - iOS, I'm using the Django Message Framework to show messages to users as well as the #login_required decorator on one of my views. So if a user tries to access a  Message levels¶ The messages framework is based on a configurable level architecture similar to that of the Python logging module. Message levels allow you to group messages by type so they can be filtered or displayed differently in views and templates. The built-in levels, which can be imported from django.contrib.messages directly, are:

It took me a while to figure out a nice way of doing this, but I think I have an implementation, based on the answer of Daniel Roseman

First thing I did was creating a decorator that sets messages when a user is not logged in, exactly like login_required.

So I wrote login_required_message:

try:
    from functools import wraps
except ImportError:
    from django.utils.functional import wraps  # Python 2.4 fallback.

from django.utils.decorators import available_attrs

from django.contrib import messages

default_message = "Please log in, in order to see the requested page."

def user_passes_test(test_func, message=default_message):
    """
    Decorator for views that checks that the user passes the given test,
    setting a message in case of no success. The test should be a callable
    that takes the user object and returns True if the user passes.
    """
    def decorator(view_func):
        @wraps(view_func, assigned=available_attrs(view_func))
        def _wrapped_view(request, *args, **kwargs):
            if not test_func(request.user):
                messages.error(request, message)
            return view_func(request, *args, **kwargs)
        return _wrapped_view
    return decorator

def login_required_message(function=None, message=default_message):
    """
    Decorator for views that checks that the user is logged in, redirecting
    to the log-in page if necessary.
    """
    actual_decorator = user_passes_test(
        lambda u: u.is_authenticated, #fixed by removing ()
        message=message,
    )
    if function:
        return actual_decorator(function)
    return actual_decorator        

With this implementation you can now annotate your view methods like this:

from decorators import login_required_message
from django.contrib.auth.decorators import login_required

@login_required_message(message="You should be logged in, in order to see the index!")
@login_required
def index(request):
    pass

Now first the message will be set, then the redirect will be performed.

However I actually don't want to add the login_required_message decorator everywhere. It would be much nicer to have only one decorator. So lets chain them (simply add this to your decorator.py file after login_required_message):

from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.decorators import login_required

def login_required_message_and_redirect(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None, message=default_message):

    if function:
        return login_required_message(
            login_required(function, redirect_field_name, login_url),
            message
        )

    return lambda deferred_function: login_required_message_and_redirect(deferred_function, redirect_field_name, login_url, message)

It took me a while to figure out this last line; but lambda's to the rescue!

Now you can replace the two decorators with only login_required_message_and_redirect: Almost there! Since actually I want to use this new login_required_message-method everywhere, I add a monkey-patch for login_required and it is used everywhere (again add to the bottom of the decorators.py file)!

from django.contrib.auth import decorators
setattr(decorators, 'login_required', login_required_message_and_redirect)

which allows me to call:

# a message will appear, since login_required is monkey patched
@login_required
def logout(request):
    pass 

# or customize the message per view
@login_required(message="You should be logged in message! Available after monkey patch")
def index(request):
    pass

Django Tips #14 Using the Messages Framework, If you did not change anything in relation to the messages framework, just skip to from django.contrib import messages @login_required def  Django message framework and login_required. 229. Django MEDIA_URL and MEDIA_ROOT. 2. Django Auth , Login Question. 915. differentiate null=True, blank=True in django. 1.

This is an old question but I still have it 10 years later. Here is the solution I came up with. It's kind of hacky but it's only 7 lines of code including the decorator. You use 2 functions.

The first is mapped to the URL path. It checks to see if the user is logged in. If the user is not logged in, it sets a message. Regardless of the user's login state, it returns with a call to the second function.

The second function does what the standard view would have done but it has the decorator on it.

def content(request):
    if request.user.is_anonymous:
        messages.warning(request, 'You must log in to view the course content.')
    return content2(request)

@login_required
def content2(request):
    return render(request, 'path/template.html')

I am assuming that your log in template already displays messages.

Like I said, it's a bit of a hack but it works really well.

I am using Django version 3.0.6

Using the Django authentication system, Only one class of user exists in Django's authentication framework, i.e., portion of your site, or send them members-only email messages. from django.contrib. auth.decorators import login_required @login_required def my_view(request): . Django 's login_required function is used to secure views in your web applications by forcing the client to authenticate with a valid logged-in User. This decorator is a handy shortcut that can reduce the amount of code in your view functions and eliminate the need for every function to have boilerplate like if not request.user.is_authenticated:.

I know it's old but it can still help others

I think to redirect an unconnected user to the login page and at the same time send a message you can proceed as follows:

from django.contrib import messages

def views(request):
    if request.user.is_anonymous:
        messages.add_message(request, messages.INFO,
                             'You must be logged in')
        return redirect('your_login_views')
    else:
        # do smothing
        return redirect(request, 'your_page.html')

User authentication in Django | Django documentation, contrib.auth' contains the core of the authentication framework, and its default models. 'django.contrib.contenttypes' is  Using the Django authentication system¶. This document explains the usage of Django’s authentication system in its default configuration. This configuration has evolved to serve the most common project needs, handling a reasonably wide range of tasks, and has a careful implementation of passwords and permissions.

Try using this: http://code.google.com/p/django-session-messages/

or use Django 1.2 (currently in Beta) and the messages framework: http://docs.djangoproject.com/en/dev/ref/contrib/messages/#ref-contrib-messages

django.contrib.auth.decorators login_required Example Python , Python code examples for the Django function login_required from the django- oscar (project website) is a framework for building e-commerce sites on top of  A brand new Django project by default comes with the messages framework installed. If you haven’t changed anything related to the messages framework, just skip the below settings for the messages framework to the next section. Otherwise, set it up: INSTALLED_APPS . django.contrib.messages . MIDDLEWARE or MIDDLEWARE_CLASSES in older versions:

Login redirect with user friendly alerts · GitHub, This module provides login required mixin for Class-Based Views. This mixin allows to To pass messages between views is used `django.contrib.messages` framework be added to `django.contrib.messages` with tag `login_required`. Django Login and Logout Tutorial. By Will Vincent; Jul 2, 2020; In this tutorial we'll learn how to configure login/logout functionality with Django's the built-in user authentication system. This is the first in a three-part series that also covers signup and password reset for a complete user authentication flow in your future Django projects.

How-to Use Custom View @decorators in Django - Better , Django also has a built-in messages framework that uses the useful built-in decorators such as @login_required , @permission_required for  By default, a brand new Django project already comes with the messages framework installed. If you did not change anything in relation to the messages framework, just skip to the next section. Otherwise, set it up: INSTALLED_APPS. django.contrib.messages; MIDDLEWARE or MIDDLEWARE_CLASSES in older versions:

Django message framework y login_required, No hay ninguna manera obvia. Lo único que le viene a la mente es escribir su propia versión del decorador que coloca un mensaje en la sesión antes de  Django message middleware and a context processor are used to implement messages. The package is able to use various backends (classes) for storing temporary messages. It is worth noting that Fallback Storage is a class set by default.

Comments
  • I love this solution, only flaw: I couldn't get the monkey-patch to work. But that's no problem, as my current project is very small (I had to replace 8 annotations, all in one file...) Thank you for sharing!
  • Yes, but this does not handle the redirect back to the first content after the user logs in. They will be redirected to the path specified in LOGIN_REDIRECT_URL.