set_language在某些情况下不会更改语言(django)

时间:2018-10-12 08:28:53

标签: django django-i18n

我具有以下菜单来更改网站中的语言:

<div class="btn-group navbar-right language menu">
    <button class="btn btn-secondary btn-sm dropdown-toggle language-btn" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        {% get_language_info for LANGUAGE_CODE as lang %}
        {{ lang.name_local }} ({{ lang.code }})
    </button>
    <div class="dropdown-menu" aria-labelledby="dropdownMenu2">

        {% get_current_language as LANGUAGE_CODE %}
        {% get_available_languages as LANGUAGES %}
        {% get_language_info_list for LANGUAGES as languages %}

        {% for language in languages %}
            <ul class="language-item">
              <form action="{% url 'set_language' %}" method="post">
                {% csrf_token %}
                <input name="next" type="hidden" value="{{ request.get_full_path }}" />
                <input name="language" type="hidden" value="{{ language.code }}" />
                <input type="submit" value="{{ language.name_local }} ({{ language.code }})" /> <span>{% if language.code == LANGUAGE_CODE %}✓{% endif %}</span>
              </form>
            </ul>
        {% endfor %}
    </div> 
</div>

显示为

Menu for changing languages

这与the form suggested by Django docs的工作原理相同,但避免了“转到”按钮来切换语言。

通常可以正确地切换语言,但在某些情况下,除非我在用户报告问题后才发现。

如果用户通过www.mydomain.com进入我的网站,它将被重定向到www.mydomain.com/en/(或/es//de/),据我所知,正在更改语言按预期工作。

但是,如果用户通过www.mydomain.com/es/进入我的网站,则在尝试通过菜单更改语言时,会再次加载www.mydomain.com/es/www.mydomain.com/de/也会发生相同的行为。

奇怪的是,通过www.mydomain.com/en/进入我的网站时,更改语言可以正常工作。也许因为这是默认语言?

如果通过隐身窗口进入该站点,我能够始终如一地复制问题。如果我通过普通窗口执行此操作,则这是类似的行为,但并不总是一致的。例如,有时候通过www.mydomain.com/en/输入也不会让我更改语言。这使我认为它可能与Cookie有关。但这是我所知。

我在几个小时内检查了类似的问题,发现的唯一类似的东西是Django票证In some cases i18n set_language does not change url language。结论是:

  

...我重新创建了问题:我们设置了一种语言(一次),然后尝试反转   再次设置语言时使用旧语言的URL。

     

这显然失败了。

     

解决方法:

     
      
  • 跟踪旧语言,然后回退以尝试使用当前语言查找失败。
  •   
  • 通过浏览器选项卡发送信号,我们已经更改了语言并进行了相应调整(???)。
  •   
     

这两者都不属于内置i18n的范围。 (第一个   在项目层面上是可能的-重新实现set_language —如果   被认为具有成本效益。)

     

我将在此基础上结束此操作。

我不确定是否也是这种情况,因为我不明白为什么它“显然会失败”。如我所见,明显的行为应该是更改语言。

令我惊讶的是,这样的基本功能无法正常工作,因此我可能丢失了一些东西。

为什么在所述情况下不起作用? 任何帮助将不胜感激。


编辑1:

以前,我使用的是翻译的URL,而不是建议的here形式。但是,由于块的平移,渲染时间为1秒。这就是为什么我决定改变

2 个答案:

答案 0 :(得分:0)

为进一步参考,我只是回过头来使用建议的here而不是表格形式的翻译URL。

我发现是什么让它变得如此缓慢。 事实证明,这是可以优化的,所以现在翻译的URL加载也非常快。

答案 1 :(得分:0)

我遇到了同样的问题。 django似乎无法转换HTTP Referer标头,这仍然是一个现有问题。

See Django source code of set_language

一种解决方法是发送一个名为next的隐藏输入字段,您将其设置为与您使用的相同网址(request.get_full_path),但将当前语言部分替换为您想要的语言切换到。

以下是解决此问题的语言切换器的摘要:

    <li {% if current_language|slice:":2"  == 'en' %} class="active"{% endif %}>
      <form method="POST" action="{% url 'set_language' %}" autocomplete="off">
        {% csrf_token %}
        <span class="language-code">en</span>
        <input type="submit" name="language" value="en">
        <input type="hidden" name="next" value="{{ request.get_full_path|replace_language:"en" }}">
      </form>
    </li>
    <li{% if current_language|slice:":2" == 'da' %} class="active"{% endif %}>
      <form method="POST" action="{% url 'set_language' %}" autocomplete="off">
        {% csrf_token %}
        <span class="language-code">dk</span>
        <input type="submit" name="language" value="da">
        <input type="hidden" name="next" value="{{ request.get_full_path|replace_language:"da" }}">
      </form>
    </li>

然后,您可以实现一个名为{_3}}的replace_language,该语言可以通过您配置的语言运行并将其替换为参数。

希望这会有所帮助:-)