Reputation: 3679
I'm trying to fix translations for a little Django project of mine. Unsing Django 2.2.12.
Current status is, that I can switch translations by setting LANGUAGE_CODE to different values. But I would like to switch translations by means of accept-language of browser - which does not seem to work. My suspicion is, that for some reason the middleware is not configured correctly.
This is what I have set for middlewares:
MIDDLEWARE_CLASSES = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
And languges:
LANGUAGES = (
('de', 'German'),
('tr', 'Turkish'),
('en', 'English'),
('it', 'Italian'),
('fr', 'French'),
)
From the documentation I conclude, that if setting of LANGUAGE_CODE changes the translation - as is the case for me - then all other means of determining the proper translation have failed (including cookies). Because LANGUAGE_CODE is evaluated in the last step.
I would like to know how I could check it the middleware is doing it's thing correclty - and why it seems to ignore accept-language. Any hints on this are highly appreciated!
Upvotes: 2
Views: 3556
Reputation: 3679
Adding my findings based on the answer of @Blackdoor:
django.utils.translation.trans_real.get_language_from_request()
returns "en"
django.utils.translation.get_language_from_path(request.path_info)
returns None
request.session.get(LANGUAGE_SESSION_KEY)
leads to an AttributeError: "'WSGIRequest' object has no attribute 'session'"
request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
returns None
request.META.get('HTTP_ACCEPT_LANGUAGE', '')
returns "en"
django.utils.translation.get_language_from_request(request)
returns "en"
settings.LANGUAGE_CODE
is set to "de"
django.utils.translation.get_language()
returns "de"
Still wondering why 'HTTP_ACCEPT_LANGUAGE' is not used - but I will fix this manually by activating the language returned by `get_language_from_request(request) ...
Upvotes: 0
Reputation: 982
With settings.USE_I18N=True
, the key codes are in django.utils.translation.trans_real.get_language_from_request()
function
which is called by LocaleMiddleware.process_request()
.
language_code is found out with priority from high to low as below.
firstly, if urlconf is handled by i18n_patterns function, it will respect the explicit language_code info in path.
lang_code = get_language_from_path(request.path_info)
if not or invalid, as respecting user, then try getting language_code out of request.session which could be set it somewhere, and usually client could post {language:'en'} to the url path of django.views.i18n.set_language(request).
lang_code = request.session.get(LANGUAGE_SESSION_KEY) # LANGUAGE_SESSION_KEY = '_language'
if not or invalid, then try getting language_code out of request.cookies as respecting client.
lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME) # LANGUAGE_COOKIE_NAME = 'django_language'
if not or invalid, then try getting the first valid language_code out of ACCEPT_LANGUAGE as respecting browser.
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '') # usually it has a lot of language info
if invalid, else:
lang_code = get_supported_language_variant(settings.LANGUAGE_CODE)
So, you can print all the related info to figure it out.
Upvotes: 2