Solid_i18n возврат к текущему языку при выборе языка по умолчанию
Я использую solid_18n urls только для того, чтобы язык по умолчанию использовался как корневой путь.
У меня есть SOLID_I18N_USE_REDIRECTS = True для перенаправления на предпочитаемый язык, который хранится в request.session, однако после выбора языка, если вы попытаетесь вернуться к языку по умолчанию с помощью представления Django i18n.set_language, он перенаправит обратно на другой язык. В итоге вы застрянете на этом языке.
Например, ваш текущий язык - испанский, и ваш текущий путь /es/whatever. Вы пытаетесь переключиться обратно на английский, который является языком по умолчанию, через /i18n/setlang/. Но вместо того, чтобы изменить язык на английский и перенаправить на /whatever, он возвращается на /es/whatever, при этом испанский остается активным.
Обратите внимание, что вы все еще можете переключиться на языки, не входящие в список по умолчанию, установив язык или браузер на соответствующий префикс. Например, /de/whatever или выбор через set_language сработает и установит немецкий язык в качестве текущего языка, сохранит его в сессии и перенаправит соответствующим образом.
Это промежуточная функция solid_i18n:
class SolidLocaleMiddleware(LocaleMiddleware):
def process_request(self, request):
check_path = self.is_language_prefix_patterns_used
language_path = get_language_from_path(request.path_info)
if check_path and not self.use_redirects:
language = language_path or self.default_lang
else:
language = trans.get_language_from_request(request, check_path)
set_language_from_path(language_path)
trans.activate(language)
request.LANGUAGE_CODE = trans.get_language()
А это Django:
def set_language(request):
"""
Redirect to a given url while setting the chosen language in the
session or cookie. The url and the language code need to be
specified in the request parameters.
Since this view changes how the user will see the rest of the site, it must
only be accessed as a POST request. If called as a GET request, it will
redirect to the page in the request (the 'next' parameter) without changing
any state.
"""
next = request.POST.get('next', request.GET.get('next'))
if not is_safe_url(url=next, host=request.get_host()):
next = request.META.get('HTTP_REFERER')
if not is_safe_url(url=next, host=request.get_host()):
next = '/'
response = http.HttpResponseRedirect(next)
if request.method == 'POST':
lang_code = request.POST.get('language', None)
if lang_code and check_for_language(lang_code):
if hasattr(request, 'session'):
request.session[LANGUAGE_SESSION_KEY] = lang_code
else:
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN)
return response
Похоже, что представление "Установить язык" просто устанавливает request.session[LANGUAGE_SESSION_KEY] на новый язык, но это происходит только после того, как SolidLocaleMiddleware получает старый язык из сессии, прежде чем представление изменит его и активирует. Таким образом, получается, что активен текущий/старый язык, а не выбранный.
Я не уверен, как решить эту проблему или правильна ли моя диагностика.