I have a really weird problem I've never seen before. I'm using Django 1.10.
I have several dictionary files:
/locale/fr/LC_MESSAGES/django.po
/locale/de/LC_MESSAGES/django.po
/locale/zh/LC_MESSAGES/django.po
The application strings are written in English. The dictionary files are complete, and compiled to mo
files.
I store each user's language preference in the language
field of the UserProfile
. When updating their profile, I apply the language translation to the session.
# 'up' is a UserProfile object pertaining to the user
up.update(language=form.cleaned_data['language'])
translation.activate(up.language)
self.request.session[translation.LANGUAGE_SESSION_KEY] = up.language
return super(self, UpdateUserProfile).form_valid(form)
This works fine for French and German. The return super
renders the form template in French/German, and then I can navigate to other pages and see French/German text.
It doesn't work for Chinese (language code 'zh'). The return super
page renders the form template in Chinese (and I've verified the language setting in the shell after saving), but then unlike French and German, all other pages revert to English when I navigate away.
I've restarted the dev server just in case it was due to old settings. I've tried it out on a clean pull of that branch on a fresh, isolated dev VM. I have the same problem for Chinese in both scenarios. What could cause this error?
Edit - additional information:
From settings.py
LANGUAGE_CODE = 'en-us'
LOCALE_PATHS = [
BASE_DIR + '/locale/',
]
USE_I18N = True
USE_L10N = True
As mentioned, on POST for the UpdateLanguage FormView
the request.session[translation.LANGUAGE_SESSION_KEY]
code is set to zh
, and the page displays in Chinese. On a GET request to the same view the page displays in English (however examining request.session[translation.LANGUAGE_SESSION_KEY]
shows it is set to zh
despite displaying English text).
I'm not using language prefixes in the urls.
You've correctly inferred that
zh
is not a code that is part of the defaultLANGUAGES
setting and thus is not working right.The reason you got Chinese when producing the first page is that you make a call equivalent to
translation.activate("zh")
. This call does not checkLANGUAGES
. It blindly activates the translation for the languagezh
. If the files are there for "zh" there's no problem. You could dotranslation.activate("turnip")
and Django would be fine with it so long as the files for the language "turnip" exist..The reason it did not work on subsequent page requests is that the locale middleware does check against
LANGUAGES
and rejects values that are not listed there: it switches back to the default language you configured for your site.Here is code that illustrates the two cases:
You'll see in the 2nd part using the middleware that when you select "zh" as the language,
request.LANGUAGE_CODE
is set to the default language for your site instead of being "zh" or some variant of it. On my system, the output is: