Django и поддержка нескольких языков

Поддержка нескольких языков в Django

Сегодня вы узнаете, как реализовать поддержку нескольких языков используя интернационализацию в приложении Django.

Введение

Django имеет встроенную поддержку нескольких языков. Чтобы добавить поддержку нескольких языков в Django, нужно выполнить определенные действия.

Предположим, что мы будем поддерживать английский и японский языки в приложении Django. Чтобы было понятнее, я разделил эту статью на этапы.

Давайте приступим!

Первый шаг

В файл settings.py внесите изменения, прописанные ниже.

Я импортирую функцию gettext_lazy:

from django.utils.translation import gettext_lazy as _

Затем я определяю список кортежей. Первым элементом в кортеже будет код языка, а вторым — метка языка:

LANGUAGES = [
    ('en', _('English')),     
    ('ja', _('Japanese')),
]

Настройки интернационализации и перевода должны быть истинными — True:

USE_I18N = True
USE_L10N = True

Далее я добавляю ключ языковой сессии и ключ языкового файла cookie. Эти ключи используются для хранения языкового кода в сеансе и в файлах cookie:

LANGUAGE_SESSION_KEY = 'session_language_appname'
LANGUAGE_COOKIE_NAME = 'cookie_language_appname' 

Я добавляю LocaleMiddleware в список промежуточных программ. Эта запись должна находиться после SessionMiddleware и до CommonMiddleware:

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

Теперь я создаю каталог «locale» в папке нашего приложения и добавляю путь (path) к LOCALE_PATHS в папке приложения, settings.py файл. Это список путей, по которым Django будет искать файлы перевода. Здесь я создаю отдельный каталог «locale» для каждого приложения:

LOCALE_PATHS = [
    os.path.join(BASE_DIR, 'app_name/locale')
]

Второй шаг

Перевод статических строк или меток в шаблоне.

В каждом шаблоне, где вы хотите перевести метки или строки, импортируйте тег шаблона i18n в верхней части страницы следующим образом:

{%% load i18n %%}

Теперь используйте шаблонный тег trans с метками на странице, как это делаю я. Например, на странице входа в систему, чтобы перевести метку «password» (пароль) в соответствии с активным языком, сделайте это:

{%% trans 'password' %%}

Я захожу в каталог приложения и выполняю приведенную ниже команду, чтобы сгенерировать файл перевода сообщения:

django-admin makemessages -l ja

Значение -l используется для обозначения языка. «Ja» — это обозначение японского языка. Значение приведет к созданию файла по указанному ниже пути:

app_name/locale/ja/LC_MESSAGES/django.po

Откройте и отредактируйте файл django.po. Вы найдете несколько записей в комбинации ‘msgid’ и ‘msgstr’. Msgid — это строковая метка по умолчанию, которая должна быть преобразована. Msgstr — это преобразованная строка. Вы увидите одну запись с ‘msgid’ равную ‘password’ и ‘msgstr’ в виде пустой строки. Найдите японский перевод слова «password» (пароль) и поставьте его напротив слова «msgstr». Повторите этот процесс для всех английских строк:

msgid "password" 
msgstr "パスワード"

Теперь скомпилируйте эти сообщения, выполнив приведенную ниже команду:

django-admin compilemessages

Это создаст еще один файл скомпилированных сообщений с таким именем django.mo в том же месте и не в удобочитаемом для человека формате.

Третий шаг

Активация второго языка в приложении Django.

Django использует свой собственный механизм для обнаружения активированного языка. Как вы можете видеть, последним резервным вариантом является LANGUAGE_CODE в файле settings.py. Измените его значение на «ja» и перезагрузите приложение. Вы увидите, что все метки в шаблонах внутри тега trans template были преобразованы. Если он работает не так, как ожидалось, пожалуйста, проверьте, присутствует ли японский эквивалент строки в файле django.po.

Четвёртый шаг

Предоставление пользователю возможности установить предпочтительный язык в приложении.

Предыдущий вариант (из третьего шага) хорош только для разработки и тестирования. Каждый пользователь должен иметь возможность установить свой собственный предпочтительный язык в приложении. Для этого мы должны предоставить возможность выбрать предпочтительный язык на веб-сайте. В заголовке (или на любой странице) вашего приложения напишите приведенный ниже код, чтобы отобразить опцию установки предпочтительного языка:

{%% get_available_languages as LANGUAGES %%}
{%% for lang in LANGUAGES %%}
{%% if LANGUAGE_CODE == lang.0 %%}
{{lang.1}} ({{lang.0}})
{%% else %%}
<a href="{%% url 'app_name:set_language' %%}?l={{lang.0}}">{{lang.1}} ({{lang.0}})</a>
{%% endif %%} |
{%% endfor %%}

Этот код перечисляет все доступные языки, выбирая список кортежей из файла settings.py. В настоящее время активный язык не доступен для кликабельности. Но я могу установить другой язык в качестве предпочтительного языка, нажав на него.

Создаю запись в файле urls.py:

urlpatterns += [
    path(r'set-language/', views.set_language, name='set_language'),
]

Далее я создаю представление с именем set_language:

@login_required
def set_language(request):
    lang = request.GET.get('l', 'en')
    request.session[settings.LANGUAGE_SESSION_KEY] = lang
    response = HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
    response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang)
    return response

Это представление устанавливает выбранный язык в сеансе, а затем в файлах cookie. После просмотра происходит перенаправление на ту же страницу, на которой мы были.

Теперь я перезагружаю приложение, и могу выбрать предпочтительный язык из заголовка приложения. Страница перезагрузится, и на нашей странице будет отображаться текст на предпочтительном языке.

Пятый шаг

Перевод текста или сообщений, возвращенных из представлений.

В нашем файле views.py, импортируйте файл gettext_lazy:

from django.utils.translation import gettext as _

Оберните текст внутри функции gettext или gettext_lazy (которая была импортирована под псевдонимом «_» ):

msg = _('No entry in table')

И снова повторите действия из шага №2.

Шестой шаг

Перевод сайта администратора Django.

Встроенные модели Django, их метки полей и общие кнопки на сайте администратора обрабатываются автоматически.

Для перевода имен пользовательских моделей используйте подробное название моделей:

class Meta:
    managed = False
    db_table = 'Person'
    verbose_name = _('Person')
    verbose_name_plural = _('Persons')

Для имен полей используйте help_text и verbose_name:

code = models.CharField(db_column='Code', primary_key=True, max_length=100, help_text=_('Code'),verbose_name=_('Code'))
name = models.CharField(db_column='Name', max_length=500, help_text=_('Name'), verbose_name=_('Name')) 

Седьмой шаг

Перевод сообщений, возвращаемых функциями Javascript.

Каждый из нас использует один или несколько фреймворков javascript, чтобы сделать некоторые базовые проверки.

Как перевести сообщения, возвращаемые функциями javascript?

У Django есть нечто под названием JavascriptCatalog, которое производит код javascript с функциями, имитирующими gettext и другие функции перевода. Пожалуйста, обратитесь к этой официальной документации Django, которая предельно понятна.

Я попытался реализовать JavascriptCatalog, но не смог заставить его работать. Поэтому я написал небольшую собственную реализацию, которая просто делает всю работу за меня в небольшом приложении.

В вашем файле javascript напишите функцию, которая принимает текст на основном языке, в нашем случае на английском, а затем возвращает переведенный текст на предпочтительном языке.

Эта функция выбирает предпочтительный язык из скрытого поля ввода, которое было создано вместе со списком всех доступных языков на шаге №4:

<input type="hidden" id="current_language_code" name="current_language_code" value="{{LANGUAGE_CODE}}">

Код Javascript:

var m = {  
    'select category': 'カテゴリを選んでください',
    'No files found for matching criteria': 'ファイルが見つかりません',
    
};

function getCurrentLanguage() {
    return document.getElementById('current_language_code').value;
}

function getLangText(text) {
    if (getCurrentLanguage() == 'ja') {
        return m[text];
    }
    return text;
}

Теперь используйте этот код для перевода сообщений, возвращаемых функциями Javascript, как показано ниже:

document.getElementById('file_msg').innerHTML = getLangText('No files found for matching criteria');

Этот подход имеет ограничения, такие как поддержка двух языков. Чтобы добавить поддержку большего количества языков, нам нужно изменить код.

Заключение

На этом разбор алгоритма по интернационализации в Django окончен. Я надеюсь, что у меня получилось объяснить материал простыми словами.

Желаю удачи в программировании!

Егор Егоров

Программирую на Python с 2017 года. Люблю создавать контент, который помогает людям понять сложные вещи. Не представляю жизнь без непрерывного цикла обучения, спорта и чувства юмора.

Ссылка на мой github есть в шапке. Залетай.

Оцените автора
Егоров Егор
Добавить комментарий