diff --git a/django/middleware/locale.py b/django/middleware/locale.py index 65a3893e9a..5643e484c6 100644 --- a/django/middleware/locale.py +++ b/django/middleware/locale.py @@ -35,7 +35,10 @@ class LocaleMiddleware(MiddlewareMixin): urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF) i18n_patterns_used, prefixed_default_language = is_language_prefix_patterns_used(urlconf) - if response.status_code == 404 and not language_from_path and i18n_patterns_used: + if (response.status_code == 404 and not language_from_path and + i18n_patterns_used and prefixed_default_language): + # Maybe the language code is missing in the URL? Try adding the + # language prefix and redirecting to that URL. language_path = '/%s%s' % (language, request.path_info) path_valid = is_valid_path(language_path, urlconf) path_needs_slash = ( diff --git a/docs/releases/1.10.4.txt b/docs/releases/1.10.4.txt index 0f1f70e95d..86ce644fdf 100644 --- a/docs/releases/1.10.4.txt +++ b/docs/releases/1.10.4.txt @@ -23,3 +23,6 @@ Bugfixes * Fixed a ``QuerySet.update()`` crash on SQLite when updating a ``DateTimeField`` with an ``F()`` expression and a ``timedelta`` (:ticket:`27544`). + +* Prevented ``LocaleMiddleware`` from redirecting on URLs that should return + 404 when using ``prefix_default_language=False`` (:ticket:`27402`). diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index 38d99fa847..8d8d4c752e 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -1860,6 +1860,20 @@ class UnprefixedDefaultLanguageTests(SimpleTestCase): response = self.client.get('/de-simple-page/') self.assertEqual(response.content, b'Yes') + def test_no_redirect_on_404(self): + """ + A request for a nonexistent URL shouldn't cause a redirect to + // when prefix_default_language=False and + // has a URL match (#27402). + """ + # A match for /group1/group2/ must exist for this to act as a + # regression test. + response = self.client.get('/group1/group2/') + self.assertEqual(response.status_code, 200) + + response = self.client.get('/nonexistent/') + self.assertEqual(response.status_code, 404) + @override_settings( USE_I18N=True, diff --git a/tests/i18n/urls_default_unprefixed.py b/tests/i18n/urls_default_unprefixed.py index 92ef8c6246..85f9bf049b 100644 --- a/tests/i18n/urls_default_unprefixed.py +++ b/tests/i18n/urls_default_unprefixed.py @@ -6,5 +6,6 @@ from django.utils.translation import ugettext_lazy as _ urlpatterns = i18n_patterns( url(r'^(?P[\w-]+)-page', lambda request, **arg: HttpResponse(_("Yes"))), url(r'^simple/$', lambda r: HttpResponse(_("Yes"))), + url(r'^(.+)/(.+)/$', lambda *args: HttpResponse()), prefix_default_language=False, )