Fixed #28216 -- Added next_page/get_default_redirect_url() to LoginView.
This commit is contained in:
parent
59841170ba
commit
b99d6c9cbc
|
@ -43,6 +43,7 @@ class LoginView(SuccessURLAllowedHostsMixin, FormView):
|
|||
"""
|
||||
form_class = AuthenticationForm
|
||||
authentication_form = None
|
||||
next_page = None
|
||||
redirect_field_name = REDIRECT_FIELD_NAME
|
||||
template_name = 'registration/login.html'
|
||||
redirect_authenticated_user = False
|
||||
|
@ -63,8 +64,7 @@ class LoginView(SuccessURLAllowedHostsMixin, FormView):
|
|||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_success_url(self):
|
||||
url = self.get_redirect_url()
|
||||
return url or resolve_url(settings.LOGIN_REDIRECT_URL)
|
||||
return self.get_redirect_url() or self.get_default_redirect_url()
|
||||
|
||||
def get_redirect_url(self):
|
||||
"""Return the user-originating redirect URL if it's safe."""
|
||||
|
@ -79,6 +79,10 @@ class LoginView(SuccessURLAllowedHostsMixin, FormView):
|
|||
)
|
||||
return redirect_to if url_is_safe else ''
|
||||
|
||||
def get_default_redirect_url(self):
|
||||
"""Return the default redirect URL."""
|
||||
return resolve_url(self.next_page or settings.LOGIN_REDIRECT_URL)
|
||||
|
||||
def get_form_class(self):
|
||||
return self.authentication_form or self.form_class
|
||||
|
||||
|
|
|
@ -47,6 +47,12 @@ Minor features
|
|||
* The default iteration count for the PBKDF2 password hasher is increased from
|
||||
260,000 to 320,000.
|
||||
|
||||
* The new
|
||||
:attr:`LoginView.next_page <django.contrib.auth.views.LoginView.next_page>`
|
||||
attribute and
|
||||
:meth:`~django.contrib.auth.views.LoginView.get_default_redirect_url` method
|
||||
allow customizing the redirect after login.
|
||||
|
||||
:mod:`django.contrib.contenttypes`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -996,17 +996,26 @@ implementation details see :ref:`using-the-views`.
|
|||
See :doc:`the URL documentation </topics/http/urls>` for details on using
|
||||
named URL patterns.
|
||||
|
||||
**Attributes:**
|
||||
**Methods and Attributes**
|
||||
|
||||
.. attribute:: template_name
|
||||
|
||||
The name of a template to display for the view used to log the user in.
|
||||
Defaults to :file:`registration/login.html`.
|
||||
|
||||
.. attribute:: next_page
|
||||
|
||||
.. versionadded:: 4.0
|
||||
|
||||
The URL to redirect to after login. Defaults to
|
||||
:setting:`LOGIN_REDIRECT_URL`.
|
||||
|
||||
.. attribute:: redirect_field_name
|
||||
|
||||
The name of a ``GET`` field containing the URL to redirect to after
|
||||
login. Defaults to ``next``.
|
||||
login. Defaults to ``next``. Overrides the
|
||||
:meth:`get_default_redirect_url` URL if the given ``GET`` parameter is
|
||||
passed.
|
||||
|
||||
.. attribute:: authentication_form
|
||||
|
||||
|
@ -1043,6 +1052,14 @@ implementation details see :ref:`using-the-views`.
|
|||
<django.http.HttpRequest.get_host>`, that are safe for redirecting
|
||||
after login. Defaults to an empty :class:`set`.
|
||||
|
||||
.. method:: get_default_redirect_url()
|
||||
|
||||
.. versionadded:: 4.0
|
||||
|
||||
Returns the URL to redirect to after login. The default implementation
|
||||
resolves and returns :attr:`next_page` if set, or
|
||||
:setting:`LOGIN_REDIRECT_URL` otherwise.
|
||||
|
||||
Here's what ``LoginView`` does:
|
||||
|
||||
* If called via ``GET``, it displays a login form that POSTs to the
|
||||
|
|
|
@ -52,8 +52,8 @@ class AuthViewsTestCase(TestCase):
|
|||
cls.u1 = User.objects.create_user(username='testclient', password='password', email='testclient@example.com')
|
||||
cls.u3 = User.objects.create_user(username='staff', password='password', email='staffmember@example.com')
|
||||
|
||||
def login(self, username='testclient', password='password'):
|
||||
response = self.client.post('/login/', {
|
||||
def login(self, username='testclient', password='password', url='/login/'):
|
||||
response = self.client.post(url, {
|
||||
'username': username,
|
||||
'password': password,
|
||||
})
|
||||
|
@ -726,6 +726,31 @@ class LoginTest(AuthViewsTestCase):
|
|||
self.login()
|
||||
self.assertNotEqual(original_session_key, self.client.session.session_key)
|
||||
|
||||
def test_login_get_default_redirect_url(self):
|
||||
response = self.login(url='/login/get_default_redirect_url/')
|
||||
self.assertRedirects(response, '/custom/', fetch_redirect_response=False)
|
||||
|
||||
def test_login_next_page(self):
|
||||
response = self.login(url='/login/next_page/')
|
||||
self.assertRedirects(response, '/somewhere/', fetch_redirect_response=False)
|
||||
|
||||
def test_login_named_next_page_named(self):
|
||||
response = self.login(url='/login/next_page/named/')
|
||||
self.assertRedirects(response, '/password_reset/', fetch_redirect_response=False)
|
||||
|
||||
@override_settings(LOGIN_REDIRECT_URL='/custom/')
|
||||
def test_login_next_page_overrides_login_redirect_url_setting(self):
|
||||
response = self.login(url='/login/next_page/')
|
||||
self.assertRedirects(response, '/somewhere/', fetch_redirect_response=False)
|
||||
|
||||
def test_login_redirect_url_overrides_next_page(self):
|
||||
response = self.login(url='/login/next_page/?next=/test/')
|
||||
self.assertRedirects(response, '/test/', fetch_redirect_response=False)
|
||||
|
||||
def test_login_redirect_url_overrides_get_default_redirect_url(self):
|
||||
response = self.login(url='/login/get_default_redirect_url/?next=/test/')
|
||||
self.assertRedirects(response, '/test/', fetch_redirect_response=False)
|
||||
|
||||
|
||||
class LoginURLSettings(AuthViewsTestCase):
|
||||
"""Tests for settings.LOGIN_URL."""
|
||||
|
|
|
@ -3,6 +3,7 @@ from django.contrib.auth import views
|
|||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.contrib.auth.urls import urlpatterns as auth_urlpatterns
|
||||
from django.contrib.auth.views import LoginView
|
||||
from django.contrib.messages.api import info
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.shortcuts import render
|
||||
|
@ -78,6 +79,11 @@ def login_and_permission_required_exception(request):
|
|||
pass
|
||||
|
||||
|
||||
class CustomDefaultRedirectURLLoginView(LoginView):
|
||||
def get_default_redirect_url(self):
|
||||
return '/custom/'
|
||||
|
||||
|
||||
# special urls for auth test cases
|
||||
urlpatterns = auth_urlpatterns + [
|
||||
path('logout/custom_query/', views.LogoutView.as_view(redirect_field_name='follow')),
|
||||
|
@ -149,6 +155,9 @@ urlpatterns = auth_urlpatterns + [
|
|||
views.LoginView.as_view(redirect_authenticated_user=True)),
|
||||
path('login/allowed_hosts/',
|
||||
views.LoginView.as_view(success_url_allowed_hosts={'otherserver'})),
|
||||
path('login/get_default_redirect_url/', CustomDefaultRedirectURLLoginView.as_view()),
|
||||
path('login/next_page/', views.LoginView.as_view(next_page='/somewhere/')),
|
||||
path('login/next_page/named/', views.LoginView.as_view(next_page='password_reset')),
|
||||
|
||||
path('permission_required_redirect/', permission_required_redirect),
|
||||
path('permission_required_exception/', permission_required_exception),
|
||||
|
|
Loading…
Reference in New Issue