12

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

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

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

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

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

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

更新

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')),
)

这似乎不起作用。但是,如果我删除并将其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')),
)

文档说您不必将其包含在其中i18n_patterns,所以我认为这应该可以,但事实并非如此!django.conf.urls.i18n如果你在之前或之后包含它并不重要,i18n_patterns它总是一样的。

4

8 回答 8

25

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

首先,让我解释一下问题:在使用i18_patternsin yoururls.py前置语言代码时,如果您调用 URLset_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>

将语言更改为按钮:

<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>
于 2013-08-23T01:21:02.330 回答
17

可能选项的总结:

更改用户的会话语言select

在Django docs上有一个很好的广泛描述示例。

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

无需像@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>

您当然可以将按钮设计为看起来像链接或其他任何东西。

更改链接显示的语言

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

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

搜索引擎优化

如果按照 Django 的建议使用表单来更改会话语言,我不完全确定内容是否对 seo 友好。因此,链接<a>标记可能被添加为隐藏在<button>元素下方。

于 2015-06-11T11:33:08.470 回答
2

如果在您当前的系统中您只有 2 种语言,那么只需使用如下所示:

{% ifequal LANGUAGE_CODE "en" %}
       <a href="/es{{ request.get_full_path }}">Spanish</a>
{% else %}
       <a href="/en{{ request.get_full_path }}">English</a>
{% endifequal %}

不需要表格、网址和提交等。它对我有用。

于 2014-12-08T10:25:06.283 回答
2

如果您只需要两种语言,例如。英语和法语,您已经在 settings.py 中定义了这一点,并且您已经设置了默认语言,并且您已经在主应用程序中正确配置了 urls.py。然后,只需在您的模板(或部分、顶栏等)btn-kinito "btn-header中使用它只是样式类,您可以使用 css 或 JS 对其进行操作。

内部的循环或迭代只是遍历LANGUAGES[]您在 中定义的列表,settings.py然后它会创建一个按钮。带有字符“|” 还有一个空间&nbsp;让它看起来很可爱,因为我们只有两个 langs。

{% url 'set_language' %}是 Django 的重定向视图,称为 set_language,它重定向到 URL。这就是为什么在你的主应用程序的 urls.py 中你需要把path('i18n/', include('django.conf.urls.i18n')),In 这种情况。因此,在为列表中的每种语言创建按钮后,您将能够被重定向到该 url。

  <div class="btn-header">
    <form action="{% url 'set_language' %}" method="post">
      {% csrf_token %}
      <input name="next" type="hidden" value="{{ redirect_to }}" />
        {% get_current_language as LANGUAGE_CODE %}
        {% get_available_languages as LANGUAGES %}
        {% get_language_info_list for LANGUAGES as languages %}
        {% for language in languages %}
          <button type="submit" name="language" value="{{ language.code }}"
            class="btn-kinito">
            {{ language.code }}
          </button>|&nbsp;
        {% endfor %}
    </form>
  </div>

对于 urls.py,我认为它可能如下所示:

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.conf.urls.i18n import i18n_patterns


# I don't want my admin translated
urlpatterns = [
    path('admin/', admin.site.urls),
]

urlpatterns += i18n_patterns (
    path('i18n/', include('django.conf.urls.i18n')),
    path('', include('pages.urls')),
    path('cats', include('cats.urls')),
    path('dogs', include('dogs.urls')),
    prefix_default_language=False,
 ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

prefix_default_language=False,是可选的,它会从 url 中删除默认语言前缀,如果您只有两种或三种语言,这很有意义。尽管我过去确实遇到过这个问题,prefix_default_language=False,但它不起作用。

如何解决prefix_default_language=False,不工作或不从 url 中删除默认语言前缀的问题

在我的 settings.py 我改变了 LANGUAGE_CODE = 'en-us'LANGUAGE_CODE = 'en'

(似乎已经解决了)

于 2020-01-29T01:02:09.550 回答
1

我知道这不是一个可靠的解决方案,但我需要一个切换按钮(不是下拉列表,因为我想在两种语言之间切换)所以我想出了这个:

{% get_language_info_list for LANGUAGES as languages %}
{% if LANGUAGE_CODE == languages.0.code %}
    <form action="{% url 'set_language' %}" method="post">
    {% csrf_token %}
    <div class="lang-btn">
        <input name="next" type="hidden" value="{{ redirect_to }}" />
        <input name="language" type="hidden" value="{{ languages.1.code }}" />
        <button type="submit"><img width="30" src="{% static 'united-kingdom.png' %}" alt=""></button>
        </div>
        </form>
{% else %}
    <form action="{% url 'set_language' %}" method="post">
    {% csrf_token %}
        <div class="lang-btn">
            <input name="next" type="hidden" value="{{ redirect_to }}" />
            <input name="language" type="hidden" value="{{ languages.0.code }}" />
            <button type="submit"><img width="30" src="{% static 'turkey.png' %}" alt=""></button>
        </div>
    </form>
{% endif %}
于 2021-10-27T07:25:03.813 回答
1

除了添加此处建议的表格:

<form action="{% url 'set_language' %}" method="post">
  {% csrf_token %}
  {{ request.get_full_path_info|slice:'3:'}}
  <input name="next" type="hidden" value="{{ languageless_url }}" />
  <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.code }}
      </button>
    </li>
    {% endfor %}
  </ul>
</form>

我建议添加一个上下文处理器(app.context_processors.py):

def language_processor(request):
"""
This is needed for language picker to work
"""
return {
    'languageless_url':
    '/' + '/'.join(request.get_full_path().split('/')[2:])
}

这允许将逻辑排除在模板之外。另外不要忘记在模板设置中添加您的处理器:

            'context_processors': [
            'app.context_processors.language_processor',
于 2019-08-21T14:18:28.247 回答
1
{% load i18n %}

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

 <div class="btn-header">
    <form action="{% url 'set_language' %}" method="post">
      {% csrf_token %}
      <input name="next" type="hidden" value="{{ redirect_to }}" />
        {% for language in languages %}
            {% if language.code != LANGUAGE_CODE %}
                <button type="submit" name="language" value="{{ language.code }}">{{ language.name }}</button>
            {% endif %}
        {% endfor %}
    </form>
  </div>

如果你有两种语言。它只会向您显示关闭的那个。

https://www.loom.com/share/9319c0e9204f417a8eec897965ce3a96

于 2020-08-15T02:28:53.180 回答
0

姜戈 3.02

<div class="uk-flex">

    {% get_current_language as LANGUAGE_CODE %}
    {% get_available_languages as LANGUAGES %}
    {% get_language_info_list for LANGUAGES as languages %}
    <div class="languages">
        <p>{% trans "Language" %}:</p>
        <ul class="languages">
        {% for language in languages %}
            <li>
                <a href="/{{ language.code }}/{{ request.get_full_path |slice:'4:'}}" {% if language.code == LANGUAGE_CODE %} class="selected"{% endif %}>
                {{ language.name_local }}
                </a>
            </li>
        {% endfor %}
        </ul>
    </div>
</div>
于 2020-05-27T04:49:19.947 回答