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

Cau*_*ons 7 python django internationalization django-i18n

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

<form action="/i18n/setlang/" method="post">{% csrf_token %}
    <input name="language" type="hidden" value="es" />
    <input type="submit" value="ES" />
</form>
Run Code Online (Sandbox Code Playgroud)

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

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

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

<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>
Run Code Online (Sandbox Code Playgroud)

更新:

进一步的测试之后,我注意到,有同时使用的问题i18n_patterns,并patternsurls.py.目前我有一个看起来像这样的文件:

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')),
)
Run Code Online (Sandbox Code Playgroud)

而这似乎不起作用.但是,如果我删除i18n_patterns并将其更改为patterns然后它似乎工作:

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

文档说你不必将它包含在里面i18n_patterns,所以我认为这应该有效,但事实并非如此!如果你django.conf.urls.i18ni18n_patterns它之前或之后包括它总是这样做并不重要.

Cau*_*ons 19

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

首先,让我解释一下这个问题:当i18_patterns你使用你urls.py的语言代码时,如果你调用URL set_language来改变语言而没有指定next,它默认为当前的,但是使用前面的旧语言代码!所以,语言又恢复原状!而且,如果您明确指定next,则必须确保在开头不包含语言代码.

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

那么,我们如何删除这些不受欢迎的语言代码,以便在使用时更改当前页面并更改语言i18n_patterns?很容易,我们只需切片3个第一个字符(斜线和两个字符语言代码)!

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

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

从列表中更改语言:

<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>
Run Code Online (Sandbox Code Playgroud)

将语言更改为按钮:

<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>
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果`prefix_default_language=False`,`{{ request.get_full_path|slice:'3:' }}` 可能会失败。最好进行检查,否则会有切割 url 有效部分的风险。 (4认同)
  • 除了上面的注释,大多数但不是所有的语言代码都有两个字母,例如。de_DE,zh-Hans,所以依赖它是危险的。`'/'.join(request.get_full_path.split('/')[1:])` 在 Python 中,例如模板标签,会更好。 (3认同)

Wto*_*wer 11

可能选项的总结:

使用a更改用户的会话语言 select

关于Django文档的例子有很好的广泛描述.

使用按钮更改用户的会话语言

没有必要像@Caumons建议的那样为每个按钮重复一个表单,而是只需在表单中包含与语言一样多的按钮.

<form action="{% url 'set_language' %}" method="post">
    {% csrf_token %}
    <input name="next" type="hidden" value="{{ request.get_full_path|slice:'3:' }}" />
    <ul class="nav navbar-nav navbar-right language menu">
        {% get_current_language as LANGUAGE_CODE %}
        {% get_available_languages as LANGUAGES %}
        {% get_language_info_list for LANGUAGES as languages %}
        {% for language in languages %}
            <li>
                <button type="submit"
                        name="language"
                        value="{{ language.code }}"
                        class="{% if language.code == LANGUAGE_CODE %}selected{% endif %}">
                    {{ language.name_local }}
                </button>
            </li>
        {% endfor %}
    </ul>
</form>
Run Code Online (Sandbox Code Playgroud)

你当然可以设置按钮的样式,看起来像链接或其他什么.

更改链接显示的语言

如果不需要更改默认用户会话语言,则可以使用简单链接更改内容:

<ul class="nav navbar-nav navbar-right language menu">
    {% get_current_language as LANGUAGE_CODE %}
    {% get_available_languages as LANGUAGES %}
    {% get_language_info_list for LANGUAGES as languages %}
    {% for language in languages %}
        <li>
            <a href="/{{ language.code }}{{ request.get_full_path|slice:'3:' }}"
               class="{% if language.code == LANGUAGE_CODE %}selected{% endif %}"
               lang="{{ language.code }}">
                {{ language.name_local }}
            </a>
        </li>
    {% endfor %}
</ul>
Run Code Online (Sandbox Code Playgroud)

SEO

如果使用表单来改变会话语言,我不完全确定内容是否友好,正如Django所建议的那样.因此,链接<a>标记可能会隐藏在<button>元素下方.