'django translation not working for me
i cant force django to translate strings, choosen language from request is correct, but i have no translated strings.
maybe here could be problem: when i run shell, returned language_code is not equal as i have in settings.py
gettext = lambda s: s
USE_I18N = True
USE_L10N = True
LANGUAGE_CODE = 'en'
LANGUAGES = (
('cs', gettext('Czech')),
('en', gettext('English')),
)
>>> from django.utils import translation
>>>
>>> translation.get_language()
'en-us'
>>> from django.conf import settings
>>> settings.LANGUAGE_CODE
'en'
my message file is in locale/cs/LC_MESSAGES/django.{mo,po}
i have this content there (translated abbr of week short names):
msgid "Mo Tu We Th Fr Sa Su"
msgstr "Po Út St Čt Pá So Ne"
in view, when i am getting right value 'cs'
print get_language()
'cs'
and next line is ugettext
ugettext('Mo Tu We Th Fr Sa Su')
'Mo Tu We Th Fr Sa Su'
but i am expecting
'Po Út St Čt Pá So Ne'
can somebody tell me where could be problem? :o)
Solution 1:[1]
It is possible that translation is in .po file however is missing in .mo file. Try recompile messages by running
./manage.py compilemessages
Solution 2:[2]
I tracked the code whole night and found some clues. Mainly in trans_real.py and gettext.py. You can put a breakpoint in "translation" function.
- The translation code are executed only once when app starts. So you need to reload the uwsgi to load the new version.
- Po file is never used. gettext.py use "mo" file only.(in my laptop). So you have to compile messages after changing.
- The "-" in the language code will be converted to "_" in locale path. For example "zh-CN" will be converted to "zh_CN". That's why the translation file cannot be found. I think it will be better if just using two characters as the language code. And the case sensitive should be considered in Linux system.
Solution 3:[3]
1. Make sure you have a correct-translated .mo file:
Execute msgunfmt ./locale/jp/LC_MESSAGES/django.mo to decompile .mo file:
Example output:
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "world"
msgstr "????"
2. Make sure Python's builtin gettext worked
Execute python under project root, enter the Python shell, then execute:
import gettext
assert gettext.translation("django", "locale", ['jp']).gettext("world") == "????"
3. Make sure LOCALE_PATHS is correctly set
Execute python manage.py under project root, enter the Django shell, then execute:
from django.conf import settings
assert len(settings.LOCALE_PATHS) > 0
4. Make sure Django's gettext worked under corresponding language context
Enter Django shell, Execute:
from django.utils import translation
with translation.override("jp"):
assert translation.gettext("world") == "????"
5. Make sure you have a standard language code, and django supports it
Enter Django shell, Execute:
from django.utils import translation
assert 'ja' in translation.trans_real.get_languages()
assert 'zh-hans' in translation.trans_real.get_languages()
assert 'zh-hant' in translation.trans_real.get_languages()
assert 'zh-cn' not in translation.trans_real.get_languages()
6. Make sure you have the correct language context
Server code:
from django.contrib import admin
from django.http import JsonResponse
from django.urls import path
from django.utils.translation import gettext_lazy, get_language
def home(_):
return JsonResponse(dict(
language=get_language(),
hello=gettext_lazy("world")
), json_dumps_params=dict(ensure_ascii=False, indent=4))
urlpatterns = [
path('admin/', admin.site.urls),
path('', home)
]
Test it:
curl 'http://localhost:8000' -H 'Accept-Language: ja'
Example response:
{
"language": "ja",
"hello": "????"
}
The required config but not in default Django project:
LOCALE_PATHSThelocalepath is required for django to find.mofilesMIDDLEWARETheLocaleMiddlewareis required for web project to detect context's language
BASE_DIR = Path(__file__).resolve().parent.parent
LOCALE_PATHS = (
BASE_DIR / "locale", # Here
)
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # And here
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Another note:
Do not execute mkdir locale to create locale folder manually, python manage.py makemessages will create locale folder if your settings worked.
The correct i18n steps for a new Django project:
- Set
LOCALE_PATHS - Set
LocaleMiddleware python manage.py makemessagespython manage.py compilemessagespython manage.py runserverto see if it worked.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | mark |
| Solution 3 |
