Opened 6 years ago

Last modified 6 years ago

#29281 closed Bug

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

Reported by: Nikita Delyukov Owned by: nobody
Component: Internationalization Version: 1.11
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 Nikita Delyukov)

In general POST to /i18n/setlang/ works fine.
Sometimes it fails: if the current link is /es/smth/ (or just /es/, whatever), post to /i18n/setlang/ with 'en' reloads the same link /es/smth/, instead of /en/smth/.
Happens from time to time in our prod, dev servers and locally. Sometimes just closing the browser window and opening the site again solves the issue. At the same time it may be fine in one browser and fail in another. Yesterday I encountered it locally and was able to debug:

# from django.views.i18n, set_language
# current link is '/es/smth/', POST to /i18n/setlang/ with language: en, csrfmiddlewaretoken: xxx
...
if request.method == 'POST':
    lang_code = request.POST.get(LANGUAGE_QUERY_PARAMETER) # ='en'
    if lang_code and check_for_language(lang_code):
        if next:# next = '/es/smth/'
            next_trans = translate_url(next, lang_code)# returns the same '/es/smth/'
            if next_trans != next:# next == next_trans, url is not changed, the same /es/smth/ url is reloaded, language haven't changed
                response = http.HttpResponseRedirect(next_trans)
...
# django.urls.base, translate_url:
...
parsed = urlsplit(url) # SplitResult(scheme='http', netloc='127.0.0.1:8080', path='/es/smth/', query='', fragment='')
try:
    match = resolve(parsed.path)# triggers Resolver404
except Resolver404:
    pass
else:
...
# django.urls.base, resolve
def resolve(path, urlconf=None): # path is the current url, /es/smth/
    if urlconf is None:
        urlconf = get_urlconf() # None
    return get_resolver(urlconf).resolve(path) # <RegexURLResolver 'proj.urls' (None:None) ^/>, resolve(path) triggers Resolver404

Resolver404: {'tried': <RegexURLResolver <RegexURLPattern list> (admin:admin) ^admin/>], [<RegexURLResolver <module 'django.conf.urls.i18n' from 'C:\\Python36\\Scripts\\aliro\\Lib\\site-packages\\django\\conf\\urls\\i18n.py'> (None:None) ^i18n/>], [<LocaleRegexURLResolver <RegexURLResolver list> (None:None) ^en/>, 'path': 'es/smth/'}

So, sometimes get_resolver(None).resolve(path) where path matches a listed i18n_pattern, fails, and in another browser the same path is matched fine.
The variables in both runs are the same until get_resolver(urlconf).resolve(path), where one triggers Resolver404, and the other returns a matched url (ResolverMatch(func=app.views.smth, args=(), kwargs={'template_name': 'app/smth.html'}, url_name=smth, app_names=[], namespaces=[]))

#proj.urls.py:
...
urlpatterns += i18n_patterns(
    url(r'^', include('app.urls')),
)
...

I don't have a setup and\or scenario to reproduce it everytime.
Django 1.11.10

Change History (1)

comment:1 by Nikita Delyukov, 6 years ago

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