diff --git a/django/contrib/auth/tests/test_views.py b/django/contrib/auth/tests/test_views.py
index d406b43..7259eda 100644
|
a
|
b
|
|
| | 1 | # -*- coding: utf-8 -*- |
| 1 | 2 | from importlib import import_module |
| 2 | 3 | import itertools |
| 3 | 4 | import re |
| … |
… |
from django.contrib.auth import SESSION_KEY, REDIRECT_FIELD_NAME
|
| 10 | 11 | from django.contrib.auth.forms import (AuthenticationForm, PasswordChangeForm, |
| 11 | 12 | SetPasswordForm) |
| 12 | 13 | from django.contrib.auth.models import User |
| 13 | | from django.contrib.auth.views import login as login_view |
| | 14 | from django.contrib.auth.views import login as login_view, redirect_to_login |
| 14 | 15 | from django.core import mail |
| 15 | | from django.core.urlresolvers import reverse, NoReverseMatch |
| | 16 | from django.core.urlresolvers import NoReverseMatch, reverse, reverse_lazy |
| 16 | 17 | from django.http import QueryDict, HttpRequest |
| 17 | 18 | from django.utils.deprecation import RemovedInDjango20Warning |
| 18 | 19 | from django.utils.encoding import force_text |
| … |
… |
class LoginRedirectUrlTest(AuthViewsTestCase):
|
| 673 | 674 | self.assertLoginRedirectURLEqual('http://remote.example.com/welcome/') |
| 674 | 675 | |
| 675 | 676 | |
| | 677 | class LazyLoginURLTest(AuthViewsTestCase): |
| | 678 | def test_redirect_to_login(self): |
| | 679 | with self.settings(LOGIN_URL=reverse_lazy('login')): |
| | 680 | login_redirect_response = redirect_to_login(next='/else/where/') |
| | 681 | expected = '/login/?next=/else/where/' |
| | 682 | self.assertEquals(expected, login_redirect_response.url) |
| | 683 | |
| | 684 | def test_redirect_to_login_with_unicode(self): |
| | 685 | with self.settings(LOGIN_URL=reverse_lazy('login')): |
| | 686 | login_redirect_response = redirect_to_login(next='/else/where/เค/') |
| | 687 | expected = '/login/?next=/else/where/%E0%A4%9D/' |
| | 688 | self.assertEquals(expected, login_redirect_response.url) |
| | 689 | |
| | 690 | |
| 676 | 691 | @skipIfCustomUser |
| 677 | 692 | class LogoutTest(AuthViewsTestCase): |
| 678 | 693 | |
diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
index 348fca8..0031785 100644
|
a
|
b
|
def redirect_to_login(next, login_url=None,
|
| 125 | 125 | |
| 126 | 126 | login_url_parts = list(urlparse(resolved_url)) |
| 127 | 127 | if redirect_field_name: |
| 128 | | querystring = QueryDict(login_url_parts[4], mutable=True) |
| | 128 | old_querystring = login_url_parts[4] |
| | 129 | querystring = QueryDict(old_querystring, mutable=True) |
| 129 | 130 | querystring[redirect_field_name] = next |
| 130 | | login_url_parts[4] = querystring.urlencode(safe='/') |
| | 131 | new_querystring = querystring.urlencode(safe='/') |
| | 132 | if isinstance(old_querystring, bytes): |
| | 133 | # login_url_parts must be all str / all bytes, not a mix in Python3 |
| | 134 | new_querystring = new_querystring.encode('utf-8') |
| | 135 | login_url_parts[4] = new_querystring |
| 131 | 136 | |
| 132 | 137 | return HttpResponseRedirect(urlunparse(login_url_parts)) |
| 133 | 138 | |
diff --git a/django/utils/functional.py b/django/utils/functional.py
index aa0d6f8..634d06e 100644
|
a
|
b
|
def lazy(func, *resultclasses):
|
| 182 | 182 | memo[id(self)] = self |
| 183 | 183 | return self |
| 184 | 184 | |
| | 185 | def decode(self, encoding='ascii', errors='strict'): |
| | 186 | """ |
| | 187 | Turn into a string as that's what Python 3 code usually wants, |
| | 188 | e.g. to pass the _coerce_args function in urlparse. |
| | 189 | |
| | 190 | :param encoding: So urllib.parse._decode_args works with this. |
| | 191 | :param errors: So urllib.parse._decode_args works with this. |
| | 192 | """ |
| | 193 | return str(self) |
| | 194 | |
| 185 | 195 | @wraps(func) |
| 186 | 196 | def __wrapper__(*args, **kw): |
| 187 | 197 | # Creates the proxy object, instead of the actual value. |