Opened 12 months ago

Last modified 12 months ago

#35034 closed Bug

In some cases i18n set_language does not change url language — at Version 1

Reported by: Eric Soroos Owned by: nobody
Component: Internationalization Version: 4.2
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Eric Soroos)

Related to #29281, but this time with repro

When posting to /i18n/setlang/:

  • with a referrer in a language that's not the current django cooke language like /km/admin/foo/bar,
  • with a current language cookie of django_language=en
  • and a post content of next=&language=en

django.urls.translate_urls attempts to resolve the url using the current request language (in this case, en) and fails, because the url is in a different language (km).

i18n.set_language then returns the original referrer in the location header of the redirect, and the language doesn't apparently change, confusing the user.

The patch for translate_urls is approximately:

from django.utils.translation import override, check_for_language, get_language_from_path

...

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:
        # URL may be encoded.                                                                                                                                                      
        try:
            match = resolve(unquote(parsed.path))
        except Resolver404:
            url_lang_code = get_language_from_path(unquote(parsed.path))
            if url_lang_code and check_for_language(url_lang_code):
                with override(url_lang_code):
                    match = resolve(unquote(parsed.path))
            else:
                raise
    except Resolver404:
        pass
    else:
...

https://github.com/django/django/compare/main...EricSoroos:django:35034-translate-url

Change History (1)

comment:1 by Eric Soroos, 12 months ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top