django语言环境如何在视图之间工作

时间:2011-08-31 13:49:04

标签: django internationalization

我知道django首先从浏览器标题中获取网站的默认语言,然后如果它与设置中的可能选择匹配则显示该语言的页面。

我要做的是改变&用户登录后设置该语言。我为用户提供了默认设置的表单。登录后,从这些defaultSettings模型中选择默认语言。我正在做的是:

d = DefaultSettings.objects.filter(user = request.user)
if len(d) > 0 and d[0].has_default_language:
    from django.utils import translation      
    translation.activate(d[0].default_language)
    request.LANGUAGE_CODE = translation.get_language()

而我所看到的是“错误”语言的页面。

这让我问 - 为什么?我自己没有编写代码。我从下面的例子中得到了它

由于所有这些示例都修改了middleware中的请求/响应 - 我是否真的必须这样做? Django是否会在请求之间重置语言并尝试在每次请求后再次“猜测”它?

为什么我的设置方式不起作用?

艾伦

第一回复后更新(来自SindriGuðmundsson):

    if form.is_valid ( ):
        if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
            redirect_to = settings.LOGIN_REDIRECT_URL
        if not form.cleaned_data [ 'remember_me' ]:
            request.session.set_expiry ( 0 )
        from django.contrib.auth import login
        login ( request, form.get_user ( ) )
        if request.session.test_cookie_worked ( ):
            request.session.delete_test_cookie ( )
        set_lang_to_user_default_language(request)
        response = HttpResponseRedirect ( redirect_to )
        d = DefaultSettings.objects.filter(user = request.user)
        if len(d) > 0 and d[0].has_default_language:                  
            from django.utils import translation
            translation.activate(d[0].default_language)
            logger.debug(translation.get_language())
            request.LANGUAGE_CODE = translation.get_language()                
            if hasattr(request, 'session'):
                logger.debug('set django_language')
                request.session['django_language'] = translation.get_language()
            else:
                logger.debug('set response cookie')
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, translation.get_language())
        return  response

当我查看日志时,我看到:

DEBUG 2011-09-01 09:08:13,379 et
DEBUG 2011-09-01 09:08:13,379 set django_language

但是当我在下一个视图中检查模板时,我打印出{{ LANGUAGE_CODE }},然后显示'en'而不是'et'

Update2:

实际上处理此视图后会发生什么: 此视图重定向到{{LANGUAGE_CODE}}的第一页是'en'内容是英文的 我在第一页{{ LANGUAGE_CODE }}之后去的第二页是'en'但内容是爱沙尼亚语 我在第二页{{LANGUAGE_CODE}}之后去的第3页是'en',内容再次是英文,并且从那里开始是英文。

所以看起来我必须创建自己的middleware以使页面保持“正确”的语言...我的问题是 - 为什么?

Update3:我的语言设置如下:

LANGUAGES = (
            ('et', gettext('Estonian')),
            ('en', gettext('English')),
            ('ru', gettext('Russian')),
            ('lv', gettext('Latvian')),
            ('lt', gettext('Lithuanian')),
            ('fi', gettext('Finnish')),
            )

但经过进一步调查后,我想我找到了解决方法。我在这个项目中使用django-cms,我关闭了cms.middleware.multilingual.MultilingualURLMiddleware并且遇到了我上面描述的问题。当我重新打开它时,一切都运行正常 - 但它工作正常,因为middleware已打开并且它将所需的参数放入每个响应中。

我最初问我的问题是 - 它是如何工作的。我之后问过为什么问题。现在,我认为,问题是 - 是否真的必须像request/response那样为每个middleware设置语言,并且像示例middlewares那样做?

3 个答案:

答案 0 :(得分:5)

建议/答案:

我也有一些奇怪的行为!因为我忘记添加'LocaleMiddleware',请仔细检查它是否存在,为了说明这是我的'MIDDLEWARE_CLASSES'的样子:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

中间件负责处理您的请求和响应,并添加语言!

还要保留“SindriGuðmundsson”的代码,这正在改变lang!

修改

再远一点!如果我们看一下LocaleMiddleware:

def process_request(self, request):
    language = translation.get_language_from_request(request)
    translation.activate(language)
    request.LANGUAGE_CODE = translation.get_language()

所以问题是!为什么Django需要那个?!答案:因为如果你使用{{LANGUAGE_CODE}}它正在从REQUEST中读取,那么LANGUAGE_CODE必须在请求中!除此以外 !它不会归还它!这就是为什么这个中间件存在! 在中间件的实际源代码中查看注释:

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

另请查看文档:{​​{3}}

答案 1 :(得分:1)

set_language第33行查看django.views.i18n。您必须在会话中为用户设置语言代码:

if hasattr(request, 'session'):
    request.session['django_language'] = lang_code
else:
    response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)

答案 2 :(得分:0)

Django CMS使用request.LANGUAGE_CODE来确定要使用的语言,如果您没有在GET或POST参数中特别要求使用某种语言。

Django CMS使用中间件MultilingualURLMiddleware来设置request.LANGUAGE_CODE。

该中间件首先在网址中查找语言前缀,然后查找语言会话密钥。

这意味着如果你想要另一种语言,你可以在会话变量中设置一次,但MultilingualURLMiddleware仍会在每次请求时设置request.LANGUAGE_CODE。