質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1486閲覧

Djangoでブラウザ言語に合わせて翻訳したい。

inotaku

総合スコア11

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/06/06 02:07

編集2019/06/07 04:20

前提・実現したいこと

すでに運用中のシステムを英語対応させたいと思っています。
ブラウザ(IE、Edge、Firefox)の言語によっての切り替え(ブラウザ言語が日本語場合は日本語表示。日本語以外の場合は、英語表示)をしたいです。

発生している問題・エラーメッセージ

GoogleでDjangoの国際化の方法を調べ、実装を行ったのですが Template(htmlファイル)やForm.pyなどの表示部分は問題なくブラウザ言語によって 言語が切り替わるのですが、システムに表示するエラーメッセージ等を定義していた 外部定義(※)から読みだしたメッセージだけはブラウザ言語によって切り替わりません。 ※message.pyとしてメッセージ一覧を記載し、view.pyにてインポートすることで表示しています。 色々とパターンを試してみた結果、どうやらmessage.pyの翻訳部分のみが、 setting.pyの中のLANGUAGE_CODEに引っ張られる形で表示されているみたいです。 ※LANGUAGE_CODEはjaにしてあるので、翻訳されないというよりは、  常に翻訳されて(ブラウザ言語が英語でも、常に日本語で表示される)困るという状況です。

該当のソースコード

Django

1【settings.py】 2 3MIDDLEWARE = [ 4 'django.middleware.security.SecurityMiddleware', 5 'django.contrib.sessions.middleware.SessionMiddleware', 6 'django.middleware.locale.LocaleMiddleware', # 多言語化対応のため追記 7 'django.middleware.common.CommonMiddleware', 8 'django.middleware.csrf.CsrfViewMiddleware', 9 'django.contrib.auth.middleware.AuthenticationMiddleware', 10 'django.contrib.messages.middleware.MessageMiddleware', 11 'django.middleware.clickjacking.XFrameOptionsMiddleware', 12] 13141516LANGUAGE_CODE = 'ja' 17 18【view.py】 19 20from g_idf_libs import config, message_conf, module 21 22def ini_display(request): 23 str_rst_message = message_conf.str_message01 \ 24 + result_dict['str_target_email'] \ 25 + message_conf.str_message02 26 27 my_dict = ({ 28 'form': form, 29 'str_rst_message': str_rst_message, 30 'insert_forms': '初期値', }) 31 32 return render(request, 'passrst.html', my_dict) 33 34【passrst.html】 35 36※"{% trans %}"で 翻訳部分は問題なくブラウザ言語によって切り替わる。 37※上記で作成した"{{ str_rst_message }}"部分のみが、settings.pyのLANGUAGE_CODEに引っ張られる。 38 39{% extends "base.html" %} 40{% load crispy_forms_tags %} 41{% load i18n %} 42 43 44{% block header %} 45 {% trans 'Password Reset' %} 46{% endblock %} 47 48{% block body %} 49 50 <form action="" method="post"> 51 <div class="g-idf-container-body"> 52 {% csrf_token %} 53 {{ str_rst_message }} 54 {% for field in form %} 55 {{ field.as_hidden }} 56 {% endfor %} 57 <br> 58 <br> 59 </div> 60 <div class="g-idf-footer"> 61 <input type="submit" name="reset" value="{% trans 'Send' %}" class="btn btn-primary"> 62 <input type="submit" name="back" value="{% trans 'Cancel' %}" class="btn btn-primary"> 63 </div> 64 </form> 65{% endblock %} 66 67 68【message.py】 69 70from django.utils.translation import ugettext as _ 71 72str_message01 = _('Reset your password and deliver a one-time password to ') 73str_message02 = _('. Please press send button below.') 74 75 76【django.po】 77 78# SOME DESCRIPTIVE TITLE. 79# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 80# This file is distributed under the same license as the PACKAGE package. 81# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. 82# 83#, fuzzy 84msgid "" 85msgstr "" 86"Project-Id-Version: PACKAGE VERSION\n" 87"Report-Msgid-Bugs-To: \n" 88"POT-Creation-Date: 2019-06-05 19:17+0900\n" 89"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 90"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" 91"Language-Team: LANGUAGE <LL@li.org>\n" 92"Language: \n" 93"MIME-Version: 1.0\n" 94"Content-Type: text/plain; charset=UTF-8\n" 95"Content-Transfer-Encoding: 8bit\n" 96"Plural-Forms: nplurals=1; plural=0;\n" 97 98#: g_idf_libs/message.py:8 99msgid "Reset your password and deliver a one-time password to " 100msgstr "パスワードをリセットし、" 101 102#: g_idf_libs/message.py:9 103msgid ". Please press send button below." 104msgstr "に仮パスワードを送付します。よろしければ、送信ボタンを押下してください。" 105 106

試したこと

html内に引数として渡されたメッセージを表示する部分が問題かとも疑いましたが
翻訳されるときには(LANGUAGE_CODEが"ja"の時は)、view.pyの中でmessage.pyを
インポートした時点ですでに翻訳されているので、あまりhtml側の問題ではないと
判断していました。

また、キャッシュ等も疑い、動作確認の際には毎回ブラウザの履歴とキャッシュファイルを削除しています。

よろしくお願いいたします!

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

LocaleMiddleware による言語の切り替えが完了する前に message.py が読み込まれてしまうことが原因ではないかと思います。

(パッと見の印象でコメントしていますが)そのようなモジュール構成にされたいのであれば、 ugettext() の代わりに ugettext_lazy() を使う必要があるのではないでしょうか。

patch

1- from django.utils.translation import ugettext as _ 2+ from django.utils.translation import ugettext_lazy as _

あるいは message.pymessage_conf.py ?)内にメッセージを直接置くのをやめて、次のような感じに書くというアプローチもありかもしれません。

patch

1from django.utils.translation import ugettext as _ 2 3def get_message(key): 4 # 利用側では `get_message('str_message01')` といった形で取得する 5 messages = { 6 'str_message01': _('Reset your password and deliver a one-time password to '), 7 'str_message02': _('. Please press send button below.'), 8 } 9 10 return messages[key];

投稿2019/06/07 04:49

gh640

総合スコア1407

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

inotaku

2019/06/07 06:23

指摘いただいた改善方法(messageを関数化)で、修正することができました。ありがとうございます。 ugettext_lazyは一度試したのですが、view.py内でのメッセージの作成中(他文字列との結合時)に、文字列として読み込まれないためか、エラーとなりugettexに戻していました。 今回の指摘で、ugettextやugettex_lazy等の仕様をぼやっとしか理解していないことを痛感しました。 もう少し理解を深められるように頑張りたいと思います。
gh640

2019/06/07 08:02

そうですか、それはよかったです :D `ugettext_lazy()` を使って文字列連結をしようとするとエラーとなることがあるのですね。私も覚えておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問