diff --git a/AUTHORS b/AUTHORS index 45c1bc56761..4b832bfdb4d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -836,6 +836,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 7791d9a7fd4..3339e30eb20 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -107,12 +107,21 @@ class LoginView(SuccessURLAllowedHostsMixin, FormView): return context -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): @@ -175,12 +184,20 @@ class LogoutView(SuccessURLAllowedHostsMixin, TemplateView): return context -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 139371d90e7..5fc3afe9b4f 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 be3b9904945..b53389a1618 100644 --- a/tests/auth_tests/test_deprecated_views.py +++ b/tests/auth_tests/test_deprecated_views.py @@ -9,9 +9,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 @@ -440,3 +441,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')