diff --git a/AUTHORS b/AUTHORS index 1479bb8786..c2a55095f2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -816,6 +816,7 @@ answer newbie questions, and generally made Django that much better: Yoong Kang Lim Yusuke Miyazaki Zachary Voase + Zach Liu Zach Thompson Zain Memon Zak Johnson diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index f8934e9edb..aa3ca10dfb 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -133,12 +133,21 @@ class LoginView(SuccessURLAllowedHostsMixin, FormView): @deprecate_current_app -def login(request, *args, **kwargs): +def login(request, template_name='registration/login.html', + redirect_field_name=REDIRECT_FIELD_NAME, + authentication_form=AuthenticationForm, + extra_context=None, redirect_authenticated_user=False): warnings.warn( 'The login() view is superseded by the class-based LoginView().', RemovedInDjango21Warning, stacklevel=2 ) - return LoginView.as_view(**kwargs)(request, *args, **kwargs) + return LoginView.as_view( + template_name=template_name, + redirect_field_name=redirect_field_name, + form_class=authentication_form, + extra_context=extra_context, + redirect_authenticated_user=redirect_authenticated_user, + )(request) class LogoutView(SuccessURLAllowedHostsMixin, TemplateView): @@ -202,12 +211,20 @@ class LogoutView(SuccessURLAllowedHostsMixin, TemplateView): @deprecate_current_app -def logout(request, *args, **kwargs): +def logout(request, next_page=None, + template_name='registration/logged_out.html', + redirect_field_name=REDIRECT_FIELD_NAME, + extra_context=None): warnings.warn( 'The logout() view is superseded by the class-based LogoutView().', RemovedInDjango21Warning, stacklevel=2 ) - return LogoutView.as_view(**kwargs)(request, *args, **kwargs) + return LogoutView.as_view( + next_page=next_page, + template_name=template_name, + redirect_field_name=redirect_field_name, + extra_context=extra_context, + )(request) _sentinel = object() diff --git a/docs/releases/1.11.5.txt b/docs/releases/1.11.5.txt index 139371d90e..5fc3afe9b4 100644 --- a/docs/releases/1.11.5.txt +++ b/docs/releases/1.11.5.txt @@ -43,3 +43,6 @@ Bugfixes * Fixed non-deterministic results or an ``AssertionError`` crash in some queries with multiple joins (:ticket:`26522`). + +* Fixed a regression in ``contrib.auth``'s ``login()`` and ``logout()`` views + where they ignored positional arguments (:ticket:`28550`). diff --git a/tests/auth_tests/test_deprecated_views.py b/tests/auth_tests/test_deprecated_views.py index 542833686a..f8d5ede5ca 100644 --- a/tests/auth_tests/test_deprecated_views.py +++ b/tests/auth_tests/test_deprecated_views.py @@ -11,9 +11,10 @@ from django.contrib.auth.forms import ( AuthenticationForm, PasswordChangeForm, SetPasswordForm, ) from django.contrib.auth.models import User +from django.contrib.auth.views import login, logout from django.core import mail from django.http import QueryDict -from django.test import TestCase, override_settings +from django.test import RequestFactory, TestCase, override_settings from django.test.utils import ignore_warnings, patch_logger from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text @@ -444,3 +445,48 @@ class SessionAuthenticationTests(AuthViewsTestCase): }) # if the hash isn't updated, retrieving the redirection page will fail. self.assertRedirects(response, '/password_change/done/') + + +@ignore_warnings(category=RemovedInDjango21Warning) +class TestLogin(TestCase): + def setUp(self): + self.factory = RequestFactory() + self.request = self.factory.get('/') + + def test_template_name(self): + response = login(self.request, 'template.html') + self.assertEqual(response.template_name, ['template.html']) + + def test_form_class(self): + class NewForm(AuthenticationForm): + def confirm_login_allowed(self, user): + pass + response = login(self.request, 'template.html', None, NewForm) + self.assertEqual(response.context_data['form'].__class__.__name__, 'NewForm') + + def test_extra_context(self): + extra_context = {'fake_context': 'fake_context'} + response = login(self.request, 'template.html', None, AuthenticationForm, extra_context) + self.assertEqual(response.resolve_context('fake_context'), 'fake_context') + + +@ignore_warnings(category=RemovedInDjango21Warning) +class TestLogout(AuthViewsTestCase): + def setUp(self): + self.login() + self.factory = RequestFactory() + self.request = self.factory.post('/') + self.request.session = self.client.session + + def test_template_name(self): + response = logout(self.request, None, 'template.html') + self.assertEqual(response.template_name, ['template.html']) + + def test_next_page(self): + response = logout(self.request, 'www.next_page.com') + self.assertEqual(response.url, 'www.next_page.com') + + def test_extra_context(self): + extra_context = {'fake_context': 'fake_context'} + response = logout(self.request, None, 'template.html', None, extra_context) + self.assertEqual(response.resolve_context('fake_context'), 'fake_context')