Author: jezdez
Date: 2010-09-10 14:38:57 -0500 (Fri, 10 Sep 2010)
New Revision: 13723

Modified:
   django/trunk/django/contrib/auth/decorators.py
   django/trunk/django/contrib/auth/tests/decorators.py
   django/trunk/django/contrib/auth/tests/urls.py
   django/trunk/django/contrib/auth/tests/views.py
   django/trunk/docs/topics/auth.txt
Log:
Added login_url argument to login_required decorator. Thanks mhlakhani and 
ericflo for the report and patch.

Modified: django/trunk/django/contrib/auth/decorators.py
===================================================================
--- django/trunk/django/contrib/auth/decorators.py      2010-09-10 19:36:51 UTC 
(rev 13722)
+++ django/trunk/django/contrib/auth/decorators.py      2010-09-10 19:38:57 UTC 
(rev 13723)
@@ -30,13 +30,14 @@
     return decorator
 
 
-def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME):
+def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, 
login_url=None):
     """
     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.is_authenticated(),
+        login_url=login_url,
         redirect_field_name=redirect_field_name
     )
     if function:

Modified: django/trunk/django/contrib/auth/tests/decorators.py
===================================================================
--- django/trunk/django/contrib/auth/tests/decorators.py        2010-09-10 
19:36:51 UTC (rev 13722)
+++ django/trunk/django/contrib/auth/tests/decorators.py        2010-09-10 
19:38:57 UTC (rev 13723)
@@ -1,12 +1,12 @@
-from unittest import TestCase
-
 from django.contrib.auth.decorators import login_required
+from django.contrib.auth.tests.views import AuthViewsTestCase
 
-
-class LoginRequiredTestCase(TestCase):
+class LoginRequiredTestCase(AuthViewsTestCase):
     """
     Tests the login_required decorators
     """
+    urls = 'django.contrib.auth.tests.urls'
+
     def testCallable(self):
         """
         Check that login_required is assignable to callable objects.
@@ -22,4 +22,24 @@
         """
         def normal_view(request):
             pass
-        login_required(normal_view)
\ No newline at end of file
+        login_required(normal_view)
+
+    def testLoginRequired(self, view_url='/login_required/', 
login_url='/login/'):
+        """
+        Check that login_required works on a simple view wrapped in a
+        login_required decorator.
+        """
+        response = self.client.get(view_url)
+        self.assertEqual(response.status_code, 302)
+        self.assert_(login_url in response['Location'])
+        self.login()
+        response = self.client.get(view_url)
+        self.assertEqual(response.status_code, 200)
+
+    def testLoginRequiredNextUrl(self):
+        """
+        Check that login_required works on a simple view wrapped in a
+        login_required decorator with a login_url set.
+        """
+        self.testLoginRequired(view_url='/login_required_login_url/',
+            login_url='/somewhere/')
\ No newline at end of file

Modified: django/trunk/django/contrib/auth/tests/urls.py
===================================================================
--- django/trunk/django/contrib/auth/tests/urls.py      2010-09-10 19:36:51 UTC 
(rev 13722)
+++ django/trunk/django/contrib/auth/tests/urls.py      2010-09-10 19:38:57 UTC 
(rev 13723)
@@ -1,5 +1,7 @@
 from django.conf.urls.defaults import patterns
 from django.contrib.auth.urls import urlpatterns
+from django.contrib.auth.views import password_reset
+from django.contrib.auth.decorators import login_required
 from django.http import HttpResponse
 from django.template import Template, RequestContext
 
@@ -14,5 +16,7 @@
     (r'^logout/custom_query/$', 'django.contrib.auth.views.logout', 
dict(redirect_field_name='follow')),
     (r'^logout/next_page/$', 'django.contrib.auth.views.logout', 
dict(next_page='/somewhere/')),
     (r'^remote_user/$', remote_user_auth_view),
+    (r'^login_required/$', login_required(password_reset)),
+    (r'^login_required_login_url/$', login_required(password_reset, 
login_url='/somewhere/')),
 )
 

Modified: django/trunk/django/contrib/auth/tests/views.py
===================================================================
--- django/trunk/django/contrib/auth/tests/views.py     2010-09-10 19:36:51 UTC 
(rev 13722)
+++ django/trunk/django/contrib/auth/tests/views.py     2010-09-10 19:38:57 UTC 
(rev 13723)
@@ -36,6 +36,16 @@
         settings.LANGUAGE_CODE = self.old_LANGUAGE_CODE
         settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
 
+    def login(self, password='password'):
+        response = self.client.post('/login/', {
+            'username': 'testclient',
+            'password': password
+            }
+        )
+        self.assertEquals(response.status_code, 302)
+        
self.assert_(response['Location'].endswith(settings.LOGIN_REDIRECT_URL))
+        self.assert_(SESSION_KEY in self.client.session)
+
 class PasswordResetTest(AuthViewsTestCase):
 
     def test_email_not_found(self):
@@ -118,15 +128,6 @@
 
 class ChangePasswordTest(AuthViewsTestCase):
 
-    def login(self, password='password'):
-        response = self.client.post('/login/', {
-            'username': 'testclient',
-            'password': password
-            }
-        )
-        self.assertEquals(response.status_code, 302)
-        
self.assert_(response['Location'].endswith(settings.LOGIN_REDIRECT_URL))
-
     def fail_login(self, password='password'):
         response = self.client.post('/login/', {
             'username': 'testclient',
@@ -228,16 +229,6 @@
 class LogoutTest(AuthViewsTestCase):
     urls = 'django.contrib.auth.tests.urls'
 
-    def login(self, password='password'):
-        response = self.client.post('/login/', {
-            'username': 'testclient',
-            'password': password
-            }
-        )
-        self.assertEquals(response.status_code, 302)
-        
self.assert_(response['Location'].endswith(settings.LOGIN_REDIRECT_URL))
-        self.assert_(SESSION_KEY in self.client.session)
-
     def confirm_logged_out(self):
         self.assert_(SESSION_KEY not in self.client.session)
 

Modified: django/trunk/docs/topics/auth.txt
===================================================================
--- django/trunk/docs/topics/auth.txt   2010-09-10 19:36:51 UTC (rev 13722)
+++ django/trunk/docs/topics/auth.txt   2010-09-10 19:38:57 UTC (rev 13723)
@@ -713,6 +713,17 @@
         def my_view(request):
             ...
 
+    .. versionadded:: 1.3
+
+    :func:`~django.contrib.auth.decorators.login_required` also takes an
+    optional ``login_url`` parameter. Example::
+
+        from django.contrib.auth.decorators import login_required
+
+        @login_required(login_url='/accounts/login/')
+        def my_view(request):
+            ...
+
     :func:`~django.contrib.auth.decorators.login_required` does the following:
 
         * If the user isn't logged in, redirect to
@@ -726,9 +737,9 @@
         * If the user is logged in, execute the view normally. The view code is
           free to assume the user is logged in.
 
-Note that you'll need to map the appropriate Django view to
-:setting:`settings.LOGIN_URL <LOGIN_URL>`. For example, using the defaults, add
-the following line to your URLconf::
+Note that if you don't specify the ``login_url`` parameter, you'll need to map
+the appropriate Django view to :setting:`settings.LOGIN_URL <LOGIN_URL>`. For
+example, using the defaults, add the following line to your URLconf::
 
     (r'^accounts/login/$', 'django.contrib.auth.views.login'),
 

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to