17

My question is a general one, but specifically my application is the login_required decorator for Django.

I'm curious if there is a way to check if a view/function has a specific decorator (in this case the login_required decorator)

I am redirecting after logging a user out, and I want to redirect to the main page if the page they are currently on has the login_required decorator. My searches have yielded no results so far.

Piper Merriam
  • 2,774
  • 2
  • 24
  • 30

2 Answers2

17

Build your own login_required decorator and have it mark the function as decorated--probably the best place to mark it would be in the func_dict.

from django.contrib.auth.decorators import login_required as django_l_r

# Here you're defining your own decorator called `login_required`
# it uses Django's built in `login_required` decorator
def login_required(func):
    decorated_func = django_l_r(func)
    decorated_func.func_dict['login_is_required'] = True
    return decorated_func

@login_required # Your decorator
def authenticatedd_view(request):
    pass

def unauthenticated_view(request):
    pass

Now you can check to see if a view was decorated like this...

# Assume `a_view` is view function
>>> a_view.func_dict.get('login_is_required',False)

If you're confused about Python decorators see this SO question/answer: How to make a chain of function decorators?

Community
  • 1
  • 1
Chris W.
  • 37,583
  • 36
  • 99
  • 136
  • "mark the function as decorated"? Why not mark each function with the proper URL-name to redirect to on logout? That would be more directly useful. – S.Lott Mar 30 '11 at 17:41
  • @S.Lott It sounds like you mean attaching either a URL or a URL-name to the view function, I believe that would be bad practice as it would be mixing your urls and views, which are expressly separated in Django. – Chris W. Mar 30 '11 at 17:46
  • @Chris W.: URL-names are referenced in views so that `reverse()` will work. Similarly, URL-names are reference in templates so that `{% url %}` will work. I'm not sure what you mean by "mixing". Can you explain further? – S.Lott Mar 30 '11 at 17:49
  • @S.Lott now you have me confused, the whole point of `reverse()` and `{% url %}` is to convert a **view function** (or a string descriptor of a view function) into a url. This is so that neither your HTML templates nor your view functions themselves need to know anything about URLs. – Chris W. Mar 30 '11 at 18:24
  • @Chris W.: URL's can have names. http://docs.djangoproject.com/en/1.3/topics/http/urls/#naming-url-patterns. That can simplify locating a standard URL from a number of view functions. Providing a standard URL name for a logout is often very, very handy. – S.Lott Mar 30 '11 at 18:29
  • @S.Lott ok, here is the disconnect, I see in the [django docs for reverse](http://docs.djangoproject.com/en/1.3/topics/http/urls/#django.core.urlresolvers.reverse) that the input to reverse _"is either the function name (either a function reference, or the string version of the name, if you used that form in urlpatterns) or the URL pattern name."_ I wasn't aware that you could use the URL pattern name. – Chris W. Mar 30 '11 at 18:33
2

It seems that your situation is as follows: 1. You have pages that are secured and behind a login-required decorator 2. You have pages that are non-secure and can be visited in both a logged-in state and anonymous state.

If I understand your requirements, you want a user to be redirected to Main Page (Assuming this to be the Welcome Page that can be visited in both a logged-in and Anonymous state) when a user logs out.

Why wouldn't you just limit the user's ability to logout from only secure pages, and then set your redirect_url on logout to the welcome screen?

arustgi
  • 818
  • 1
  • 8
  • 13
  • +1: That's what view functions are for. A logout view function can use `if request.user.is_anonymous()` to determine whether or not to log someone out, and which page to display. – S.Lott Mar 30 '11 at 18:40
  • Yes, but if you are trying to log them out and redirect them back to the page they logged out from, this does not work unless you can know if that page/view is protected with authentication. – Piper Merriam May 25 '11 at 12:34