djangodjango-messages

Django messages framework - lack of i18n by default


By default django messages framework does not localize it's messages correctly. For example in admin interface

enter image description here

As you can see all other things in admin panel are localized. The translation file exists. Here is my settings.


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    ...
]

MIDDLEWARE = [
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.locale.LocaleMiddleware',
]

LANGUAGE_CODE = 'ru' # I've tried 'ru-RU'

TIME_ZONE = 'Europe/Moscow'

USE_I18N = True

USE_L10N = True

USE_TZ = True

How to fix this? Thanks in advance. I have django version 3.0.6. This error also is absent in django 1.8


Solution

  • It was a breaking change from django/django@42b9a23 (Django 3.0+) that only updated the French translations.

    You can patch DjangoTranslation.gettext to handle the smart quotes.

    def _patch_gettext():
        from django.utils.translation.trans_real import DjangoTranslation
        _gettext = DjangoTranslation.gettext
    
        def gettext(self, message):
            text = _gettext(self, message)
            if text is message and '“' in message:
                new_message = message.replace('“', '"').replace('”', '"')
                new_text = _gettext(self, new_message)
                if new_text is not new_message:
                    return new_text
            return text
    
        DjangoTranslation.gettext = gettext
    

    About patching

    Subclass AppConfig in mysite/apps.py:

    from django.apps import AppConfig
    
    
    class MySiteAppConfig(AppConfig):
        name = 'mysite'
    
        def ready(self):
            _patch_gettext()
    

    Put the dotted path to that subclass in INSTALLED_APPS in mysite/settings.py:

    INSTALLED_APPS = [
        ...
        'mysite.apps.MySiteAppConfig',
    ]
    

    Reference: https://docs.djangoproject.com/en/3.0/ref/applications/#configuring-applications