尝试从 Django 模板更改语言的问题

问题描述

我需要包含两个按钮或链接,以允许用户在英语和西班牙语之间切换语言.我已阅读 文档 并尝试了这个:

I need to include two buttons or links to allow users change language between English and Spanish. I've read the docs and tried this:

<form action="/i18n/setlang/" method="post">{% csrf_token %}
    <input name="language" type="hidden" value="es" />
    <input type="submit" value="ES" />
</form>

但是,每次我单击按钮时,页面都会重新加载,但语言根本没有改变.我错过了什么吗?

However, every time I click the button, the page is reloaded but the language doesn't change at all. Am I missing something?

注意:我没有设置next,因为我只是想以所需的语言重新加载当前页面.

Note: I haven't set next, as I just want to reload the current page in the desired language.

如果我使用文档提供的默认表单,结果是一样的:页面重新加载但语言没有改变:

If I use the default form provided by the docs the result is the same: the page reloads but language isn't changed:

<form action="{% url 'set_language' %}" method="post">
    {% csrf_token %}
    <input name="next" type="hidden" value="{{ redirect_to }}" />
    <select name="language">
        {% get_language_info_list for LANGUAGES as languages %}
        {% for language in languages %}
            <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
                {{ language.name_local }} ({{ language.code }})
            </option>
        {% endfor %}
    </select>
    <input type="submit" value="Go" />
</form>

更新:

经过进一步测试,我注意到在 urls.py 中同时使用 i18n_patternspatterns 存在问题.目前我有一个看起来像这样的文件:

After further testing, I've noticed that there is a problem using both i18n_patterns and patterns in the urls.py. Currently I have a file that looks like:

urlpatterns = i18n_patterns('',
    url(r'^contents/', include('contents.urls')),
    url(r'^events/', include('events.urls')),
    # ...
)
urlpatterns += patterns('',
    url(r'^i18n/', include('django.conf.urls.i18n')),
)

这似乎不起作用.但是,如果我删除 i18n_patterns 并将其更改为 patterns 那么它似乎可以工作:

And this doesn't seem to work. However, if I remove the i18n_patterns and change it to patterns then it seems to work:

urlpatterns = patterns('',
    url(r'^contents/', include('contents.urls')),
    url(r'^events/', include('events.urls')),
    # ...
)
urlpatterns += patterns('',
    url(r'^i18n/', include('django.conf.urls.i18n')),
)

文档说您不必将它包含在 i18n_patterns 中,所以我认为这应该可以,但它没有!是否在 i18n_patterns 之前或之后包含 django.conf.urls.i18n 都没关系,它总是一样的.

The docs say that you don't have to include it inside i18n_patterns, so I think this should work, but it doesn't! It doesn't matter if you include django.conf.urls.i18n before or after i18n_patterns it always does the same.


解决方案

经过更多测试,感谢@AronYsidoro 链接的相关问题 我终于找到了问题和一个非常简单的解决方案,实际上解决了这个问题.

After more testing and thanks to the related question linked by @AronYsidoro I've finally found the issue and a very simple solution that actually solves this.

首先,让我解释一下问题:在 urls.py 中使用 i18_patterns 来添加语言代码时,如果您调用 URL set_language 更改语言而不指定 next,它默认为当前语言,但带有前置的旧语言代码!所以,语言回到了原来的!而且,如果您明确指定 next,则必须确保不要在开头包含语言代码.

First, let me explain the problem: When working with i18_patterns in your urls.py to prepend the language code, if you call the URL set_language to change the language without specifying next, it defaults to the current one, but with the prepended old language code! So, the language gets back to the original! And, if you explicitly specify next, you must be sure to do not include the language code at the begining.

如果使用 {{ request.path }}{{ request.get_full_path }} 指定 next 为当前页面这不起作用,因为它也会返回语言代码.

If you use {{ request.path }} or {{ request.get_full_path }} to specify the next as the current page this won't work as it returns the language code too.

那么,当使用 i18n_patterns 时,我们如何删除这个不需要的语言代码以重新加载当前页面并更改语言?很简单,我们只需要将前 3 个字符(斜线和两个字符的语言代码)切片!

So, how do we remove this undesired language code to reload the current page with the language changed when using i18n_patterns? Easy, we just have to slice the 3 first chars (the slash and the two chars language code)!

这里有两个例子.第一个以选择的形式(以语言为选项),另一个以按钮的形式(每种语言).

Here you have two examples. The first one in form of a select (with the languages as choices) and the other one in form of a button (per language).

我真的希望这对其他人有所帮助.您可以复制并粘贴代码,它应该可以工作.但是,如果使用按钮形式",您只需将语言设置为您想要的!

I really hope this helps someone else. You can just copy and paste the code and it should work. However, if using the "button form", you just have to set the language to your desired!

从列表中更改语言:

<form action="{% url 'set_language' %}" method="post">
  {% csrf_token %}
  <input name="next" type="hidden" value="{{ request.get_full_path|slice:'3:' }}" />
  <select name="language">
    {% get_language_info_list for LANGUAGES as languages %}
      {% for language in languages %}
        <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
          {{ language.name_local }} ({{ language.code }})
        </option>
      {% endfor %}
  </select>
  <input type="submit" value="Change" />
</form>

将语言更改为按钮:

<form action="{% url 'set_language' %}" method="post">
  {% csrf_token %}
  <input name="next" type="hidden" value="{{ request.get_full_path|slice:'3:' }}" />
  <input name="language" type="hidden" value="es" />
  <input type="submit" value="ES" />
</form>

相关文章