如果没有表单选择和提交按钮,我怎么能使用Django i18n / setlang?

时间:2016-08-28 21:24:11

标签: django django-forms django-i18n

我需要在Django中将语言选择器渲染为无序列表,例如:

<ul>
  ...
  <li><a href="???">EN</a></li>
  <li><a href="???">FR</a></li>
<ul>

我在没有i18n/set_language的情况下使用Django i18n_pattern,如果我使用documentation中提供的下面的表单,它的效果非常好:

{% load i18n %}

<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
    <input name="next" type="hidden" value="{{ redirect_to }}" />
    <select name="language">
        {% get_current_language as LANGUAGE_CODE %}
        {% get_available_languages as LANGUAGES %}
        {% 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>

我希望继续使用i18n/set_language,但使用<li>结构,不使用<select>格式和提交按钮。

有可能吗?我怎么能这样做?

3 个答案:

答案 0 :(得分:5)

正如该链接所解释的那样,内置的set_language视图需要POST,您无法通过链接进行操作(除非使用Javascript)。

但是下一部分Explicitly setting the active language为您提供了编写自己的视图所需的所有详细信息,可以从URL中获取参数。所以:

def set_language_from_url(request, user_language):
    translation.activate(user_language)
    request.session[translation.LANGUAGE_SESSION_KEY] = user_language
    return redirect(' ...somewhere... ')

并给它一个网址:

url(r'/set_language/(?P<user_language>\w+)/$', set_language_from_url, name="set_language_from_url")

现在你可以做到:

<li><a href="{% url "set_language_from_url" user_language="en" %}">EN</a></li>
<li><a href="{% url "set_language_from_url" user_language="fr" %}">FR</a></li>

答案 1 :(得分:2)

我真的不喜欢必须进行2次点击(一次用于选择语言,另一次用于点击&#34; Go&#34;提交它),所以我找到了解决办法。它仍然是一种形式,但它就像一个列表:

正如here所述,可以使用按钮而不是链接:

<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>

然后,根据Bootstrap Dropdown docs

  

历史上下拉菜单内容必须是链接,但那不是   v4的情况更长。现在您可以选择使用元素   在你的下拉菜单而不是s。

将两者合并并用css调整一下,使其看起来像一个列表,这就是我的样子:

Language dropdown menu screenshot

CSS

.language-btn{
    background-color: #c9f0dd;
    border: 1px solid #c9f0dd;
    border-radius: 2px;
    color: #0C4B33;
    font-size: 10px;
    margin-right: 5px;
}

.navbar-right{
    margin-right: 20px;
}

.dropdown-menu{
    min-width: inherit;
}

.fake-btn{
    background-color: transparent;
    border: none;
    color: rgb(150,150,150);
    height: 12px;
    font-size: 11px;
}

.no-margins{
    margin: 0;
    padding: 0;
}

.selected{
    color: #0C4B33;
}

HTML

<div class="btn-group nav navbar-nav 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">
      <form action="{% url 'set_language' %}" method="post">
          {% csrf_token %}
          <input name="next" type="hidden" value="{{ request.get_full_path|slice:'3:' }}" />
              {% 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="no-margins">
                      <button type="submit"
                              name="language"
                              value="{{ language.code }}"
                              class="{% if language.code == LANGUAGE_CODE %}selected{% endif %} dropdown-item fake-btn">
                          {{ language.name_local }} ({{ language.code }})
                      </button>
                  </ul>
              {% endfor %}
      </form>
  </div>
</div>

答案 2 :(得分:0)

不要忘了像Django文档所说的那样包含此路径:

https://docs.djangoproject.com/en/3.0/topics/i18n/translation/#miscellaneous

path('i18n/', include('django.conf.urls.i18n')),