Search code examples
pythondjangopinax

How can I modify Django's login_required decorator on a custom Pinax installation?


I would like to have Django's @login_required decorator test whether a particular field on a User has been set to something other than None. (The added field has null = true and a default of None.)

Newly created User objects do indeed have a value of None for the field, but an obvious change to @login_required has made no discernible difference in the behavior (I restarted Gunicorn to ensure a fresh read). @login_required views are rendered if the user is authenticated, even if the added field is None.

The present, slightly changed @login_required is:

def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME):
    """
    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.foo != None,
        redirect_field_name=redirect_field_name
    )
    if function:
        return actual_decorator(function)
    return actual_decorator

The original lambda was on u.is_authenticated().


Solution

  • I see from your code, that you have actually encountered user_passes_test and this in fact is what you should use instead of modifying the source code of login_required directly.

    user_passes_test() takes a required argument: a callable that takes a User object and returns True if the user is allowed to view the page. Note that user_passes_test() does not automatically check that the User is not anonymous.

    You just create a function that ensures that your conditions are met. This makes sure that everything stays inside your code base (an update to django will not break your app) and makes it so much easier to debug.

    your test function might be.

    def is_foo(user):
       if user.is_authenticated() and user.foo :
           return True