GAE上Django i18n多语言切换失效问题排查与解决
Django 4.0.2 + GAE标准环境下语言切换失效问题
问题描述
- 站点主语言为英语,第二语言为荷兰语;切换语言时URL正确变为
/nl,但页面仍显示英文文本 - 本地开发环境下语言切换正常,仅GAE线上环境出现该异常
环境与异常细节
- 使用
django-rosetta工具管理翻译 - GAE控制台中发现两个应用实例目录:
workspace/和srv/,两者在/workspace/locale/nl/LC_MESSAGES/django.po路径下均有相同的.mo文件 - 系统无报错日志,代码中检查
.mo文件存在性返回True - 本地环境根目录为项目名称,GAE上项目根目录名为
workspace,通过ROOT_DIR构建的文件路径对locale及其他配置均正常生效
关键配置代码
Settings配置
ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent _locale_dir = ROOT_DIR / "locale" _locale_file = _locale_dir / "nl/LC_MESSAGES/django.po" print(f"--- {_locale_file.is_file() = }") LOCALE_PATHS = [ROOT_DIR / "locale", "/workspace/locale", "/srv/locale"] APPS_DIR = ROOT_DIR / "lettergun" TIME_ZONE = "CET" LANGUAGE_CODE = "en" USE_I18N = True # USE_L10N = True # Deprecated in Django 4 USE_TZ = True LOCALE_PATHS = [ROOT_DIR / "locale", "/workspace/locale", "/srv/locale"] LANGUAGES = ( ("en", _("English")), ("nl", _("Dutch")), ) MIDDLEWARE = [ ... "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", ... ] # TRANSLATION USING ROSETTA # ------------------------------------------------------------------------------ ROSETTA_MESSAGES_PER_PAGE = 20 ROSETTA_ENABLE_TRANSLATION_SUGGESTIONS = True DEEPL_AUTH_KEY = "e3b5c854-f059-2f86-6ebb-5eeafc3c57a6" ROSETTA_LANGUAGE_GROUPS = True ROSETTA_SHOW_AT_ADMIN_PANEL = True
URL配置
from django.conf.urls.i18n import i18n_patterns urlpatterns: URLList = i18n_patterns( # base app path("", include("lettergun.apps.base.urls", namespace="base")), path("blog/", include(wagtail_urls)), ... etc ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += [ # API base url path("api/", include("config.api_router")), # DRF auth token path("auth-token/", obtain_auth_token), ]
模板代码
{% load i18n %} ... {% get_current_language as CURRENT_LANGUAGE %} {% get_available_languages as AVAILABLE_LANGUAGES %} {% get_language_info_list for AVAILABLE_LANGUAGES as languages %} ... {% for language in languages %} <span class="inline-block"> <a class=" {% if language.code == CURRENT_LANGUAGE %} font-bold {% endif %} px-1" href="/{{ language.code }}/"> {% if language.name_local == "English" %} EN {% elif language.name_local == "Nederlands" %} NL {% endif %} </a> </span> {% endfor %}
排查与解决建议
- 确保.mo文件正确编译:本地开发时
django compilemessages会生成.mo文件,GAE部署时需在构建阶段执行该命令,可在app.yaml的entrypoint中添加python manage.py compilemessages && ...,避免仅部署.po文件导致翻译失效 - 精简LOCALE_PATHS配置:当前配置重复定义且包含冗余路径,建议仅保留
ROOT_DIR / "locale",避免Django加载错误目录下的翻译文件 - 验证实际加载的翻译路径:在代码中打印
LOCALE_PATHS的实际解析值,确认GAE环境中Django实际读取的是哪个目录下的.mo文件 - 优化语言切换URL生成:模板中手动拼接URL可能存在路径问题,建议使用
{% url %}标签结合命名空间生成正确的切换链接,例如:<a href="{% url 'base:home' %}" hreflang="{{ language.code }}"> {% if language.code == 'en' %}EN{% else %}NL{% endif %} </a> - 清理GAE旧实例:
workspace/和srv/可能是部署残留的临时目录,重新部署应用并清理旧版本实例,确保只有当前版本的翻译文件存在
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

