在django视图中设置语言

时间:2010-02-25 19:03:22

标签: django internationalization

背景 当支付服务在幕后追回支付结果时调用该视图 - 之后我需要以正确的语言发送电子邮件以确认付款等等。我可以从支付服务器的请求中获取语言代码,并希望将其与Django的i18n系统一起使用,以确定将我的电子邮件发送到哪种语言。

所以我需要在视图中设置我的django应用程序的语言。然后一次性完成模板渲染和电子邮件发送。

设置request.session['django_language'] = lang仅在我测试时影响下一个视图。

还有其他办法吗?

干杯,

8 个答案:

答案 0 :(得分:78)

引用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)是重要的一点。

答案 1 :(得分:12)

请务必在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

答案 2 :(得分:3)

有时您希望为给定视图强制使用某种语言,但让浏览器语言设置选择其他视图的语言。我还没想出如何更改视图代码中的语言,但是你可以通过实现一个简单的中间件来实现这个目的

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
    ...
)

不是一个优雅的解决方案,但它有效。

答案 3 :(得分:3)

您可以考虑将该语言存储在用户模型中,并使用此自定义中间件django-user-language-middleware

通过查看user.language字段中的所选语言,您可以轻松翻译Django应用程序,并且您始终可以了解任何用户的语言偏好。

用法:

  1. 为您的用户模型添加语言字段:

    class User(auth_base.AbstractBaseUser, auth.PermissionsMixin):
        # ...
        language = models.CharField(max_length=10,
                                    choices=settings.LANGUAGES,
                                    default=settings.LANGUAGE_CODE)
    
  2. 从pip安装中间件:

    pip install django-user-language-middleware

  3. 将其添加到设置中的中间件类列表以侦听请求:

    MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
        ...
        'user_language_middleware.UserLanguageMiddleware',
        ...
    ]
    
  4. 我希望将来可以帮助人们登陆这个问题。

答案 4 :(得分:2)

request.LANGUAGE_CODE如果 LocaleMiddleware 已激活

答案 5 :(得分:2)

如果只是想出于某种原因获取某种语言的翻译字符串,可以use override as a decorator这样:

from django.utils import translation
from django.utils.translation import ugettext as _

with translation.override(language):
    welcome = _('welcome')

答案 6 :(得分:1)

如果您使用的是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

答案 7 :(得分:0)

使用基于类的视图,这应该有效:

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而不是最初的真实。