From 8128f440ee74dd72f9204f657f6180a128dc8eaf Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 26 Nov 2005 07:20:07 +0000 Subject: [PATCH] Fixed #903 -- Added login_url argument to user_passes_test view decorator. Didn't add it to login_required decorator because that would turn login_required into a callable decorator, which would break backwards compatibility. git-svn-id: http://code.djangoproject.com/svn/django/trunk@1440 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/views/auth/login.py | 9 +++++---- django/views/decorators/auth.py | 7 ++++--- docs/authentication.txt | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/django/views/auth/login.py b/django/views/auth/login.py index 6950ad7efe481..3f2bd43015a9a 100644 --- a/django/views/auth/login.py +++ b/django/views/auth/login.py @@ -6,6 +6,7 @@ from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect REDIRECT_FIELD_NAME = 'next' +LOGIN_URL = '/accounts/login/' def login(request): "Displays the login form and handles the login action." @@ -39,10 +40,10 @@ def logout(request, next_page=None): # Redirect to this page until the session has been cleared. return HttpResponseRedirect(next_page or request.path) -def logout_then_login(request): +def logout_then_login(request, login_url=LOGIN_URL): "Logs out the user if he is logged in. Then redirects to the log-in page." - return logout(request, '/accounts/login/') + return logout(request, login_url) -def redirect_to_login(next): +def redirect_to_login(next, login_url=LOGIN_URL): "Redirects the user to the login page, passing the given 'next' page" - return HttpResponseRedirect('/accounts/login/?%s=%s' % (REDIRECT_FIELD_NAME, next)) + return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, next)) diff --git a/django/views/decorators/auth.py b/django/views/decorators/auth.py index a5a28bb0b28ce..478f0ac84d8fb 100644 --- a/django/views/decorators/auth.py +++ b/django/views/decorators/auth.py @@ -1,4 +1,6 @@ -def user_passes_test(test_func): +from django.views.auth import login + +def user_passes_test(test_func, login_url=login.LOGIN_URL): """ Decorator for views that checks that the user passes the given test, redirecting to the log-in page if necessary. The test should be a callable @@ -6,10 +8,9 @@ def user_passes_test(test_func): """ def _dec(view_func): def _checklogin(request, *args, **kwargs): - from django.views.auth.login import redirect_to_login if test_func(request.user): return view_func(request, *args, **kwargs) - return redirect_to_login(request.path) + return login.redirect_to_login(request.path, login_url) return _checklogin return _dec diff --git a/docs/authentication.txt b/docs/authentication.txt index c1d8694499ebe..d31e2ced79119 100644 --- a/docs/authentication.txt +++ b/docs/authentication.txt @@ -314,6 +314,26 @@ Here's the same thing, using Python 2.4's decorator syntax:: Note that ``user_passes_test`` does not automatically check that the ``User`` is not anonymous. +**New in the Django development version**: ``user_passes_test()`` takes an +optional ``login_url`` argument, which lets you specify the URL for your login +page (``/accounts/login/`` by default). + +Example in Python 2.3 syntax:: + + from django.views.decorators.auth import user_passes_test + + def my_view(request): + # ... + my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')(my_view) + +Example in Python 2.4 syntax:: + + from django.views.decorators.auth import user_passes_test + + @user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/') + def my_view(request): + # ... + Limiting access to generic views --------------------------------