Search code examples
python-3.xdjangogoogle-app-enginegoogle-app-engine-pythondjango-i18n

How to set up Django i18n on Google App Engine (GAE)?


Using Django 4.0.2, and GAE standard, the site text does not change when a language is selected. The main language is english. The second language is Dutch. If I switch the language, then the url changes and includes /nl instead of en/, but the English text remains. On localhost, the English text is replaced with the Dutch text.

I'm using django-rosetta and on GAE its dashboard finds two instances of my application, called workspace/ and srv/. Each contains the same .mo file in the same location /workspace/locale/nl/LC_MESSAGES/django.po. I dont know why there are two applications, or if this is relevant. On localhost, I have one application in the expected location.

There are no errors, and checking the existence of the .mo file returns True.

My locale directory is in the project root. On local this is my project name, on GAE the name of the project root directory is workspace. This should be fine because building file paths using ROOT_DIR still works as expected for locale settings and also all other settings.

The relevant settings are:

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 config

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),
]

Template example

{% 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 %}
 

Solution

  • The problem was caused by an auto-generated .gcloudignore file including .mo files.

    If the catalog file is missing, Django wont raise an error.