Проблема при попытке изменить язык из шаблона Django

мне нужно включить две кнопки или ссылки, чтобы пользователи могли менять язык между английским и испанским. Я читал документы и попытался это:

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

однако, каждый раз, когда я нажимаю кнопку, страница перезагружается но язык не меняется вообще. Я что-то упускаю?

примечание: Я не 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>

обновление:

после дальнейшего тестирования я заметил, что есть проблема с использованием обоих i18n_patterns и patterns на urls.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 ответов


после дополнительного тестирования и благодаря вопрос связанный @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>

изменить язык как кнопка:

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

сумма возможных вариантов:

измените язык сеанса пользователя с помощью 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>

SEO

Я не совсем уверен, что контент является seo дружественным, если форма используется для изменения языка сеанса, как рекомендует Django. Поэтому возможно, что ссылка <a> разметка добавляется в качестве скрытый под <button> элемент.


вот ссылка:

Django: i18n-изменить язык

может иметь то, что вы ищете при изменении языка.


Если в вашей текущей системе у вас есть только 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 %}

нет необходимости в форме, url и отправить и т. д. У меня получилось.