在另一个版本中," set_language没有工作"问题的类别,我有这个头颅。
在我的页面中,我有一个由三部分组成的语言选择器:
隐藏表格
<form action="{% url 'set_language' %}" method="post" id="language-form" name="language-form">
{% csrf_token %}
<input type="hidden" name="language" id="language" value="" />
</form>
Javascript表单提交功能
function set_language(code) {
$('#language').val(code);
$('#language-form').submit();
}
和html列表(此处显示为在浏览器中呈现,而不是模板语言):
<li class="active"><a href="javascript:set_language('en-gb')"><img src="/static/img/locale/en-gb.png"> Great Britain (English) (en-gb)</a></li>
<li><a href="javascript:set_language('nl-be')"><img src="/static/img/locale/nl-be.png"> Belgium (Dutch) (nl-be)</a></li>
<li><a href="javascript:set_language('fr-be')"><img src="/static/img/locale/fr-be.png"> Belgium (French) (fr-be)</a></li>
<li><a href="javascript:set_language('nl-nl')"><img src="/static/img/locale/nl-nl.png"> Netherlands (Dutch) (nl-nl)</a></li>
<li><a href="javascript:set_language('fy-nl')"><img src="/static/img/locale/fy-nl.png"> Netherlands (Frisian) (fy-nl)</a></li>
我可以确认上述功能符合预期,并提交包含以下内容的POST请求:
csrfmiddlewaretoken=5Vcs9XdvHs7uJwPg4BHtnVPhPW3mMT0w&language=nl-nl
并且开发服务器看到帖子,如下所示:
[08/Jul/2015 23:58:33]"POST /i18n/setlang/ HTTP/1.1" 302 0
[08/Jul/2015 23:58:33]"GET /en-gb/ HTTP/1.1" 200 6738
我还可以确认手动输入时各种网站网址是否有效,因此我可以转到localhost/en-gb/foo
和localhost/fr-be/foo
。
我已经明确地排除了表单中的下一个字段,以便重定向返回到当前页面(并且也按预期工作)。
问题在于,虽然所有这些事情都在触发,但重定向后语言不会被更改。
我的Cookie似乎没有任何语言数据。我试图在输出中显示session._language值 - 如你所料那样失败,所以我试过了:
{% with settings.LANGUAGE_SESSION_KEY as langkey %}
<p>Lang: {{ request.session.langkey }} {{ langkey }}</p>
{% endwith %}
返回&#34;郎:&#34;那就是它(即看起来它没有设置或为空)。
我现在不知所措。我相信set_language应该从/en-gb/foo
重定向到/fr-be/foo
,但这不会发生。查看了代码调用后,我还可以从set_language code确认check_for_language(lang_code)
当lang_code == 'fr-be'
返回true时(就像我设置中指定的所有其他语言一样 - 见下文),并返回false,例如&f;&#39; ff&#39;。对于&#39; en&#39;,&#39; fr,&#39; nl&#39;和&#39; fy&#39;的值也会返回true。即使他们不作为网址工作(他们也会导致404错误)。
任何人都可以:
谢谢
Settings.py
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
ROOT_URLCONF = 'wp4.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.core.context_processors.i18n',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-gb'
LANGUAGES = (
('en-gb', _('Great Britain (English)')),
('nl-be', _('Belgium (Dutch)')),
('fr-be', _('Belgium (French)')),
('nl-nl', _('Netherlands (Dutch)')),
('fy-nl', _('Netherlands (Frisian)')),
)
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
答案 0 :(得分:5)
好的,进一步观察的几点已经产生了以下答案和意见。
首先回答我的具体问题:
这是我在审查django代码和路径时冒险的意见。
我认为set_language()
code和documentation存在逻辑错误。这或许更像是对代码所说的内容的期望,因为文档将下一个分辨率列为:
我离开next
空洞思考触发第2步。我的期望是,如果新语言是&#39; fr-be&#39;,它会将网址从/nl-be/foo/bar/
转换为/fr-be/foo/bar/
。它没有。相反,它设置为保留为/nl-be/foo/bar/
,然后将session._language值设置为&#39; fr-be&#39;。然后在加载页面时忽略此会话值,因为locale middleware(get_language_from_request()
)通过首先在URL中查找语言代码来处理请求,并且只有在找不到时才会处理请求一,它是否会查看其他选项(例如会话,cookie,请求数据,设置)。
这意味着&#39; fr-be&#39;的会话值被忽略,有利于&#39; nl-be&#39;在url中,然后在渲染模板之前清除会话值(这就是为什么当我在模板中查询时会发现会话值为None)。
我认为这是一个逻辑错误,因为如果你想改变语言并让i18n运行,那么url总是会有你当前语言的语言代码,所以第2步总会产生在语言变化中被忽略。
虽然我将使用我的解决方法(即确保每个页面都知道自己的网址减去语言代码前缀,并明确将其设置为next
值) ,我认为这是应该改变的(或者至少是明确的文档,你可以使用第二种确定下一种方法来改变语言)。