Loading django/core/urlresolvers.py +25 −1 Original line number Diff line number Diff line Loading @@ -24,7 +24,8 @@ from django.utils.functional import cached_property, lazy from django.utils.http import RFC3986_SUBDELIMS, urlquote from django.utils.module_loading import module_has_submodule from django.utils.regex_helper import normalize from django.utils.translation import get_language from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.translation import get_language, override # SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for # the current thread (which is the only one we ever access), it is assumed to Loading Loading @@ -652,3 +653,26 @@ def is_valid_path(path, urlconf=None): return True except Resolver404: return False def translate_url(url, lang_code): """ Given a URL (absolute or relative), try to get its translated version in the `lang_code` language (either by i18n_patterns or by translated regex). Return the original URL if no translated version is found. """ parsed = urlsplit(url) try: match = resolve(parsed.path) except Resolver404: pass else: to_be_reversed = "%s:%s" % (match.namespace, match.url_name) if match.namespace else match.url_name with override(lang_code): try: url = reverse(to_be_reversed, args=match.args, kwargs=match.kwargs) except NoReverseMatch: pass else: url = urlunsplit((parsed.scheme, parsed.netloc, url, parsed.query, parsed.fragment)) return url django/views/i18n.py +4 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ import os from django import http from django.apps import apps from django.conf import settings from django.core.urlresolvers import translate_url from django.template import Context, Engine from django.utils import six from django.utils._os import upath Loading Loading @@ -37,6 +38,9 @@ def set_language(request): if request.method == 'POST': lang_code = request.POST.get('language', None) if lang_code and check_for_language(lang_code): next_trans = translate_url(next, lang_code) if next_trans != next: response = http.HttpResponseRedirect(next_trans) if hasattr(request, 'session'): request.session[LANGUAGE_SESSION_KEY] = lang_code else: Loading docs/releases/1.9.txt +2 −1 Original line number Diff line number Diff line Loading @@ -127,7 +127,8 @@ Generic Views Internationalization ^^^^^^^^^^^^^^^^^^^^ * ... * The :func:`django.views.i18n.set_language` view now properly redirects to :ref:`translated URLs <url-internationalization>`, when available. Management Commands ^^^^^^^^^^^^^^^^^^^ Loading tests/i18n/patterns/tests.py +13 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import os from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import ( clear_url_caches, reverse, set_script_prefix, clear_url_caches, reverse, set_script_prefix, translate_url, ) from django.http import HttpResponsePermanentRedirect from django.middleware.locale import LocaleMiddleware Loading Loading @@ -135,6 +135,18 @@ class URLTranslationTests(URLTestCaseBase): with translation.override('pt-br'): self.assertEqual(reverse('users'), '/pt-br/usuarios/') def test_translate_url_utility(self): with translation.override('en'): self.assertEqual(translate_url('/en/non-existent/', 'nl'), '/en/non-existent/') self.assertEqual(translate_url('/en/users/', 'nl'), '/nl/gebruikers/') # Namespaced URL self.assertEqual(translate_url('/en/account/register/', 'nl'), '/nl/profiel/registeren/') self.assertEqual(translation.get_language(), 'en') with translation.override('nl'): self.assertEqual(translate_url('/nl/gebruikers/', 'en'), '/en/users/') self.assertEqual(translation.get_language(), 'nl') class URLNamespaceTests(URLTestCaseBase): """ Loading tests/view_tests/locale/nl/LC_MESSAGES/django.mo +42 B (557 B) File changed.No diff preview for this file type. View original file View changed file Loading
django/core/urlresolvers.py +25 −1 Original line number Diff line number Diff line Loading @@ -24,7 +24,8 @@ from django.utils.functional import cached_property, lazy from django.utils.http import RFC3986_SUBDELIMS, urlquote from django.utils.module_loading import module_has_submodule from django.utils.regex_helper import normalize from django.utils.translation import get_language from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.translation import get_language, override # SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for # the current thread (which is the only one we ever access), it is assumed to Loading Loading @@ -652,3 +653,26 @@ def is_valid_path(path, urlconf=None): return True except Resolver404: return False def translate_url(url, lang_code): """ Given a URL (absolute or relative), try to get its translated version in the `lang_code` language (either by i18n_patterns or by translated regex). Return the original URL if no translated version is found. """ parsed = urlsplit(url) try: match = resolve(parsed.path) except Resolver404: pass else: to_be_reversed = "%s:%s" % (match.namespace, match.url_name) if match.namespace else match.url_name with override(lang_code): try: url = reverse(to_be_reversed, args=match.args, kwargs=match.kwargs) except NoReverseMatch: pass else: url = urlunsplit((parsed.scheme, parsed.netloc, url, parsed.query, parsed.fragment)) return url
django/views/i18n.py +4 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ import os from django import http from django.apps import apps from django.conf import settings from django.core.urlresolvers import translate_url from django.template import Context, Engine from django.utils import six from django.utils._os import upath Loading Loading @@ -37,6 +38,9 @@ def set_language(request): if request.method == 'POST': lang_code = request.POST.get('language', None) if lang_code and check_for_language(lang_code): next_trans = translate_url(next, lang_code) if next_trans != next: response = http.HttpResponseRedirect(next_trans) if hasattr(request, 'session'): request.session[LANGUAGE_SESSION_KEY] = lang_code else: Loading
docs/releases/1.9.txt +2 −1 Original line number Diff line number Diff line Loading @@ -127,7 +127,8 @@ Generic Views Internationalization ^^^^^^^^^^^^^^^^^^^^ * ... * The :func:`django.views.i18n.set_language` view now properly redirects to :ref:`translated URLs <url-internationalization>`, when available. Management Commands ^^^^^^^^^^^^^^^^^^^ Loading
tests/i18n/patterns/tests.py +13 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import os from django.core.exceptions import ImproperlyConfigured from django.core.urlresolvers import ( clear_url_caches, reverse, set_script_prefix, clear_url_caches, reverse, set_script_prefix, translate_url, ) from django.http import HttpResponsePermanentRedirect from django.middleware.locale import LocaleMiddleware Loading Loading @@ -135,6 +135,18 @@ class URLTranslationTests(URLTestCaseBase): with translation.override('pt-br'): self.assertEqual(reverse('users'), '/pt-br/usuarios/') def test_translate_url_utility(self): with translation.override('en'): self.assertEqual(translate_url('/en/non-existent/', 'nl'), '/en/non-existent/') self.assertEqual(translate_url('/en/users/', 'nl'), '/nl/gebruikers/') # Namespaced URL self.assertEqual(translate_url('/en/account/register/', 'nl'), '/nl/profiel/registeren/') self.assertEqual(translation.get_language(), 'en') with translation.override('nl'): self.assertEqual(translate_url('/nl/gebruikers/', 'en'), '/en/users/') self.assertEqual(translation.get_language(), 'nl') class URLNamespaceTests(URLTestCaseBase): """ Loading
tests/view_tests/locale/nl/LC_MESSAGES/django.mo +42 B (557 B) File changed.No diff preview for this file type. View original file View changed file