问题:
我正在开发一个支持多种语言的 Django 应用程序。我正在使用基于令牌的身份验证,并尝试根据用户个人资料中存储的偏好来更改经过身份验证的用户的语言。然而,我遇到了一些关于如何应用翻译的问题,特别是在动态消息翻译方面。
我有: 我在settings.py(LANGUAGES)中设置了多种语言,并将默认语言配置为英语(LANGUAGE_CODE = 'en')。 我正在使用基于令牌的身份验证(rest_framework.authtoken)来对用户进行身份验证。用户的首选语言作为preferred_language存储在数据库中。 我添加了一个自定义中间件来根据用户的偏好来处理语言切换,该中间件应该在用户通过身份验证并设置会话后立即应用。 问题: 语言首选项似乎适用于静态内容(如模板),但在设置用户的首选语言后,视图中字符串的动态翻译(使用 gettext)无法正确应用。 例如,虽然语言更改部分起作用(例如 UI 内容),但使用 gettext() 生成的消息(例如错误或成功消息)仍然以默认语言 (en) 显示,而不是用户的首选语言(例如,es 代表西班牙语) )。 以下是一些观察结果:
当我使用 get_language() 检查视图中的活动语言时,它正确反映了会话的首选语言。 我已验证会话和 cookie (cookie_language_tinocoloco) 中的首选语言均已正确设置。 LocaleMiddleware 配置为激活语言,但它不适用于动态消息。 我尝试过的: 我已确保中间件顺序正确。 SessionMiddleware 在 LocaleMiddleware 之前,LocaleMiddleware 在 AuthenticationMiddleware 之前,这与推荐设置一致。 我已使用 Translation.activate(user.preferred_language) 手动激活中间件中的语言。 我的设置: 中间件配置(相关片段):
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware", # Ensuring session is set before locale
"django.middleware.locale.LocaleMiddleware", # Language activation middleware
"django.contrib.auth.middleware.AuthenticationMiddleware", # Authentication for token
# Other middleware
]
Custom Language Middleware:
from django.utils import translation
def get_user_language(user):
if user and hasattr(user, 'preferred_language') and user.preferred_language:
return user.preferred_language
return None
class LanguageMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if hasattr(request, 'user') and request.user.is_authenticated:
language = get_user_language(request.user)
if language:
translation.activate(language) # Activate user preferred language
response = self.get_response(request)
return response
会话 Cookie:我还确保语言首选项存储在会话和 cookie 中。
预期行为: 我希望动态翻译(使用 gettext() 和 gettext_lazy())根据用户的首选语言进行更改。但是,尽管设置了正确的语言首选项,但网站中只有某些部分(例如模板)反映了新语言,而其他部分(例如动态生成的消息)仍然以默认语言 (en) 显示。
问题: 我的设置中是否缺少某些内容,可以允许动态翻译字符串尊重经过身份验证的用户的首选语言? 在会话和 cookie 中设置用户语言后,如何确保翻译在全局范围内应用,包括动态消息? 对此的任何指导或建议将不胜感激。谢谢!
根据您定义错误消息的位置,可能会在中间件中设置活动语言之前评估
gettext()
调用。
为了说明这一点,这里是来自 Django 项目的一个片段,其中设置了翻译:
In [2]: from django.utils.translation import gettext, gettext_lazy, activate
In [3]: foo = gettext("Cows")
In [4]: bar = gettext_lazy("Cows")
In [5]: activate('ta')
In [6]: foo2 = gettext("Cows")
In [7]: bar2 = gettext_lazy("Cows")
In [8]: print("foo =", foo, "bar =", bar, "foo2 =", foo2, "bar2 =", bar2)
foo = Cows bar = பசுக்கள் foo2 = பசுக்கள் bar2 = பசுக்கள்
在这里您可以看到
gettext()
如何立即获取文本,而 gettext_lazy()
则等待直到被评估(即打印时)。
因此,如果您使用
gettext_lazy()
而不是 gettext()
,那么您的字符串将仅在渲染响应时进行评估,这应该使其使用正确翻译的字符串。希望这有帮助。