Search code examples
pythonpython-3.xdjangointernationalizationdjango-i18n

Django multi-language does not load the custom-translated files when changing the user language but only works when LANGUAGE_CODE explicitly set


when I change the language of the user by URL or calling translation.activate(lang_code) only the default texts are translated and the custom translation that I created not loading, but if I change the LANGUAGE_CODE to the target language in the settings file the translation shows without any issue. but I want when to change the user language show the custom translations that I create

its my model:

from django.db import models
from django.utils.translation import gettext as _

class Test(models.Model):
    test = models.CharField(
        max_length=100,
        verbose_name=_("test text"),
        )

my admin:

from django.contrib import admin
from lng.models import Test

@admin.register(Test)
class TestModelAdmin(admin.ModelAdmin):
    ...

my settings:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    "django.middleware.locale.LocaleMiddleware", # Here !
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
LANGUAGE_CODE = 'en'

TIME_ZONE = 'UTC'

USE_I18N = True
USE_L10N = True

USE_TZ = True

LOCALE_PATHS = [
    BASE_DIR / 'locale/',
]   

my urls :

from django.urls import path ,include
from django.conf.urls.i18n import i18n_patterns
urlpatterns = [
    path('i18n/', include('django.conf.urls.i18n')),
]

translatable_urls = [
    path('admin/', admin.site.urls),
]
urlpatterns += i18n_patterns(*translatable_urls)

my project structure:

.
├── db.sqlite3
├── lng
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── locale
│   ├── en
│   │   └── LC_MESSAGES
│   │       ├── django.mo
│   │       └── django.po
│   └── fa
│       └── LC_MESSAGES
│           ├── django.mo
│           └── django.po
├── manage.py
└── Test
    ├── asgi.py
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

8 directories, 19 files

my fa po file:

#: lng/models.py:6
msgid "test text"
msgstr "متن تستی"

enter image description here enter image description here


Solution

  • the main issue is that I used gettext which only once time loads the translation when you use it in the model fields or forms and at that time the Django starts and the default language code is used. and even if you change it the gettext doesn't update itself but gettext_lazy every time checks and loads the translations based on the current data

    so I changed my model to :

    from django.db import models
    from django.utils.translation import gettext_lazy as _
    
    class Test(models.Model):
        test = models.CharField(
            max_length=100,
            verbose_name=_("test text"),
            )