sers
sers

Reputation: 3679

Django translations: setting of LANGUAGE_CODE working - accept-languages not?

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

Answers (2)

sers
sers

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

Blackdoor
Blackdoor

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

Related Questions