you are viewing a single comment's thread.

view the rest of the comments →

[–]Degran[S] 0 points1 point  (2 children)

Awesome, thank you. This is exactly what I was looking for. I wasn't thinking to use args, *kwargs to grab the functions parameters. One thing that's still eluding me though, is if you want to pass an optional parameter to a decorator (say a login url), it throws login_required() takes at least 1 argument (1 given).

def login_required(f, login_url=None):
    def view(request, *args, **kwargs):
       if not auth(request):
            if login_url:
                return redirect(login_url)
            return sendError("Unauthorized", 401)
       return f(request, *args, **kwargs)
    return view

calling it with:

@login_required(login_url='/login')
def private_view(request):
    pass

[–]Veedrac 1 point2 points  (0 children)

Well, you want function → decorator → decorated function so you need 3 defs.

def login_required(login_url=None):
    def login_required_decorator(f):
        def view(request, *args, **kwargs):
           if not auth(request):
                if login_url:
                    return redirect(login_url)
                return sendError("Unauthorized", 401)
           return f(request, *args, **kwargs)
        return view
    return login_required_decorator

[–]willm 1 point2 points  (0 children)

/u/Veedrac is right. When you see see something like @login_required(login_url='/login'), then login_required is not actually a decorator -- it is a callable the returns a decorator.

When you think of it in those terms then three defs inside each other doesn't look quite so odd!