newbsie
newbsie

Reputation: 125

Django internationalization isn't redirecting correctly when switching language?

I internationalized a website and translations are working by visiting same URL with different language prefix i.e. /en/home and /de/home works with its respective language.

However, when switching languages using the Django built-in view setlang, I always get the redirect URL back without any change to the language prefix i.e. at /en/home and switching to German should redirect to/de/home/, but instead I get /en/home

Doing some debugging, and poking around within Django, I found that a function called translate_url() isn't correctly returning the proper url. Unfortunately, going deeper gets a little hairy for me and I'm tearing my hair out. Clicking on the function name above gives you the exact line giving me problems.

Does anyone have any clue what may be wrong?

urls.py:

urlpatterns = [
    url(r'^i18n/', include('django.conf.urls.i18n')),
    url(r'^admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

urlpatterns += i18n_patterns(
    url(r'^', include('website.urls')),
)

website/urls.py:

urlpatterns = [
    url(r'^contact/$',
        ContactFormView.as_view(form_class=CustomContactForm),
        name='contact_form'),
    url(r'^contact/sent/$',
        TemplateView.as_view(
            template_name='contact_form/contact_form_sent.html'),
        name='contact_form_sent'),
    url(r'^$', TemplateView.as_view(template_name="website/home.html")),
]

template:

{% load staticfiles %}
{% load i18n %}
{% load website_tags %}
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES_AVAILABLE %}

            <form action="{% url 'set_language' %}" method="post">
                <div class="language_choice">
                    <label for="language">Language</label>
                    <div class="lang_drp">
                        {% csrf_token %}
                        <select name="language" id="language">
                            {% for code, name in LANGUAGES_AVAILABLE %}
                            <option value="{{ code }}" {% if code == LANGUAGE_CODE %}selected{% endif %}>{{ name }}</option>
                            {% endfor %}
                        </select>
                    </div>
                </div>
            </form>

settings.py:

# MIDDLEWARE CONFIGURATION
# -----------------------------------------------------------------------------
MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# TEMPLATE CONFIGURATION
# -----------------------------------------------------------------------------
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(APPS_DIR, 'templates')
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'django.template.context_processors.i18n',
            ],
        },
    },
]

# LANGUAGE CONFIGURATION
# -----------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/topics/i18n/
USE_I18N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n
USE_L10N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code
LANGUAGE_CODE = 'de'

# Language name string is always native, that is to ensure that if reader don't
# understand the current language displayed, the user would still be able to
# recognize the native name of their language.
LANGUAGES = [
    ('en', 'English'),
    ('de', 'Deutsch'),
]

LOCALE_PATHS = [
    os.path.join(APPS_DIR, 'locale'),
]

Upvotes: 2

Views: 2282

Answers (2)

Ovezdurdy
Ovezdurdy

Reputation: 61

After change language with django-modeltranslation redirecting to home ?

If you want to redirect to the same page, you can replace this part of code:

index.html:

{% 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 }}/
          {% if language.code == LANGUAGE_CODE %} class="selected"{% endif %}>
          {{ language.name_local }}
        </a>
      </li>
    {% endfor %}
  </ul>
</div>

to:

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

Attention please:

<a href="/{{ language.code }}/

replaced to <a href="/{{ language.code }}/{{request.get_full_path|slice:"4:"}}"

Upvotes: 1

newbsie
newbsie

Reputation: 125

So I found the problem. Apparently, you MUST include a next parameter/input field that correspond to the current path (without the language prefix) in order for the redirect to work.

I erroneously assumed, this was automatically figured out by Django.

Upvotes: 1

Related Questions