Opened 3 years ago

Last modified 19 months ago

#32886 assigned Bug

Translation: clash between language cookie and i18n_patterns URLs

Reported by: Seb G Owned by: Charlie Overton
Component: Internationalization Version: 3.2
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Summary

When using i18n_patterns, language cookie is disregarded, even in non-i18n_patterns views.

Description

Given the following project urls.py file:

from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
]

urlpatterns += i18n_patterns(
    path("app/", include("app.urls", namespace="app")),
    prefix_default_language=False,
)

Browsing to /admin/ with a valid django_language cookie whose value is fr still returns an english-translated page.

This behavior seems to emerge from the LocaleMiddleware.process_request method:

def process_request(self, request):
    urlconf = getattr(request, 'urlconf', settings.ROOT_URLCONF)
    
    # This returns (True, False) because i18n_patterns are indeed used (albeit not on the requested route)
    i18n_patterns_used, prefixed_default_language = is_language_prefix_patterns_used(urlconf)
    
    # This returns "fr" as expected from the django_language cookie
    language = translation.get_language_from_request(request, check_path=i18n_patterns_used)
    
    # This returns None since, indeed, this route does not use i18n_patterns
    language_from_path = translation.get_language_from_path(request.path_info)

    # This test passes (somewhat unfortunately)
    if not language_from_path and i18n_patterns_used and not prefixed_default_language:
        # This gets executed and reverts language to default language (en)
        language = settings.LANGUAGE_CODE

    # "en" gets activated instead of "fr"
    translation.activate(language)
    request.LANGUAGE_CODE = translation.get_language()

Steps to reproduce

Using the provided test project

  1. python manage.py migrate
  2. python manage.py createsuperuser
  3. python manage.py runserver
  4. Browse to /admin/
  5. Login as superuser
  6. Edit your own user to set its language to "fr". Verify that you now have a django_language=fr cookie
  7. Browse to any admin page => not translated to "fr"

Expected behavior

Cookie language should be respected on routes that do not use i18n_patterns. It is ok though that path language overrides cookie language on routes that do use i18n_patterns.

Attachments (1)

test_project.zip (20.7 KB ) - added by Seb G 3 years ago.

Download all attachments as: .zip

Change History (4)

by Seb G, 3 years ago

Attachment: test_project.zip added

comment:1 by Claude Paroz, 3 years ago

Triage Stage: UnreviewedAccepted

Thanks for the well-prepared ticket.

comment:2 by Charlie Overton, 3 years ago

Owner: changed from nobody to Charlie Overton
Status: newassigned

I'll start working on this issue.

comment:3 by sergioisidoro, 19 months ago

I've drafted something that I think will solve this issue:
https://github.com/django/django/pull/16142

Note: See TracTickets for help on using tickets.
Back to Top