How to Pass continue url to Login Required Decorator
-
12-12-2019 - |
Question
I have login_required
decorator as follows:
def login_required(function):
""" Decorator to check Logged in users."""
def check_login(self, *args, **kwargs):
if not self.auth.get_user_by_session():
self.redirect('/_ah/login_required')
else:
return function(self, *args, **kwargs)
return check_login
Now I have a Page
(which is rendered by a seperate Handler
) where I have an option for users to upload image which can be viewed both by guests and users. As soon as the form is posted it is handled by another Handler
which uses the @login_required
decorator.
What I want to achieve is passing a continue_url
variable that I can use in the check_login
function while redirecting so that the user gets redirected back to the same page after logging in.
Solution
So basically, it sounds like you want to pass an argument to the decorator when you use it. Python does support this. The basic idea is that @decorated(argument) def foo(...)
is equivalent to def foo(...); foo = decorated(argument)(foo)
.
So you need to make decorated
be something such that decorated(argument)
can decorate foo
. There are several recipes for this. Here's one - make decorated
a class with a __call__
method, so that decorated(argument)
is a callable object that stores argument
and uses it when called:
class decorator(object):
def __init__(argument):
self.argument = argument
def __call__(self, wrapped):
def wrapper(args_for_wrapped):
do_something_with(self.argument)
wrapped(args_for_wrapped)
whatever_else_this_needs_to_do()
return wrapper
This can also be achieved with a plain function (and an additional level of nesting), with tricks involving functools.partial
etc.
OTHER TIPS
The create_login_url
function takes the destination url as its first parameter. You can get the dest_url from the request object.
def login_required(func):
def _wrapper(request, *args, **kw):
user = users.get_current_user()
if user:
return func(request, *args, **kw)
else:
return request.redirect(users.create_login_url(request.get_url()))
return _wrapper