Сегодня вы узнаете, как реализовать поддержку нескольких языков используя интернационализацию в приложении 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 окончен. Я надеюсь, что у меня получилось объяснить материал простыми словами.
Желаю удачи в программировании!