背景: 当支付服务在后台返回支付结果时,会调用该视图 - 之后我需要以正确的语言发送电子邮件以确认付款等。我可以从支付服务器的请求中获取语言代码,并希望将其与 Django 的 i18n 系统一起使用来确定以哪种语言发送电子邮件。
所以我需要从视图中设置 django 应用程序的语言。然后一次性完成我的模板渲染和电子邮件发送。
设置
request.session['django_language'] = lang
仅影响我测试时的下一个视图。
还有其他方法吗?
干杯,
盖伊
引用 Django 的 Locale Middleware (
django.middleware.locale.LocaleMiddleware
) 的部分内容:
from django.utils import translation
class LocaleMiddleware(object):
"""
This is a very simple middleware that parses a request
and decides what translation object to install in the current
thread context. This allows pages to be dynamically
translated to the language the user desires (if the language
is available, of course).
"""
def process_request(self, request):
language = translation.get_language_from_request(request)
translation.activate(language)
request.LANGUAGE_CODE = translation.get_language()
translation.activate(language)
是重要的一点。
一定要在process_response中也添加deactivate,否则不同线程会出现问题。
from django.utils import translation
class LocaleMiddleware(object):
"""
This is a very simple middleware that parses a request
and decides what translation object to install in the current
thread context. This allows pages to be dynamically
translated to the language the user desires (if the language
is available, of course).
"""
def process_request(self, request):
language = translation.get_language_from_request(request)
translation.activate(language)
request.LANGUAGE_CODE = translation.get_language()
def process_response(self, request, response):
translation.deactivate()
return response
您可以考虑将语言存储在用户模型中并使用这个自定义中间件django-user-language-middleware。
通过查看
user.language
字段中所选的语言,您可以轻松翻译 Django 应用程序,并且您始终可以了解任何用户的语言偏好。
用途:
向您的用户模型添加语言字段:
class User(auth_base.AbstractBaseUser, auth.PermissionsMixin):
# ...
language = models.CharField(max_length=10,
choices=settings.LANGUAGES,
default=settings.LANGUAGE_CODE)
从 pip 安装中间件:
pip install django-user-language-middleware
将其添加到设置中的中间件类列表中以监听请求:
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'user_language_middleware.UserLanguageMiddleware',
...
]
我希望这可以帮助人们将来解决这个问题。
有时您希望对给定视图强制使用某种语言,但让浏览器语言设置为其余视图选择语言。我还没有弄清楚如何更改视图代码中的语言,但您可以通过实现一个简单的中间件来做到这一点
lang_based_on_url_middleware.py:
from django.utils import translation
# Dictionary of urls that should use special language regardless of language set in browser
# key = url
# val = language code
special_cases = {
'/this/is/some/url/' : 'dk',
'/his/is/another/special/case' : 'de',
}
class LangBasedOnUrlMiddleware(object):
def process_request(self, request):
if request.path_info in special_cases:
lang = special_cases[request.path_info]
translation.activate(lang)
request.LANGUAGE_CODE = lang
在settings.py中:
MIDDLEWARE_CLASSES = (
...
'django.middleware.locale.LocaleMiddleware',
'inner.lang_based_on_url_middleware.LangBasedOnUrlMiddleware', # remember that the order of LocaleMiddleware and LangBasedOnUrlMiddleware matters
...
)
这不是一个优雅的解决方案,但它确实有效。
如果您使用 django 1.10 或更高版本,自定义中间件有一个新语法:
from django.utils import translation
class LocaleMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
language_code = 'en' #TODO, your logic
translation.activate(language_code)
response = self.get_response(request)
translation.deactivate()
return response
request.LANGUAGE_CODE
如果 LocaleMiddleware 已激活。
对于基于类的视图,这应该有效:
class YourView(SomeBuiltInView):
def get(self, request, *args, **kwargs):
setattr(request, 'LANGUAGE_CODE', 'YOUR_LANGUAGE_CODE')
return super().get(self, request, *args, **kwargs)
基本上,您所做的就是让视图渲染器认为请求来自
YOUR_LANGUAGE_CODE
,而不是最初的真实情况。