Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: i18n - change language

I'm install model_translation, rosetta, locale_url. But does not work change language.

My settings.py:

LANGUAGE_CODE = 'ru'
MODELTRANSLATION_TRANSLATION_REGISTRY = "project.translation"
TRANSLATION_REGISTRY = "project.translation"
ugettext = lambda s: s
LANGUAGES = (
    ('ru', ugettext(u'Russian')),
    ('uk', ugettext(u'Ukrainian')),
)

My view for a language switch:

def set_language(request):
    next = request.REQUEST.get('next', None)
    if not next:
        next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = '/'
    response = http.HttpResponseRedirect(next)
    if request.method == 'GET':
        lang_code = request.GET.get('language', None)
        if lang_code and check_for_language(lang_code):
            if hasattr(request, 'session'):
                request.session['django_language'] = lang_code
            else:
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
    return response

In templates:

<a href="{% url set_lang %}?lang=uk&next={{request.path}}">Ukranian</a>

My middleware:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'localeurl.middleware.LocaleURLMiddleware',
    'django.middleware.common.CommonMiddleware',  
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.csrf.CsrfResponseMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

But the language switching does not work. If I turn on the link http://localhost/uk/ language switch, but when switching to another page - the language back to the default language. What should I do?

like image 761
Taras Avatar asked Mar 30 '11 17:03

Taras


2 Answers

I faced the same problem and it was because the next parameter is prepended with the old language code and this prevents the new one to take effect. (Thanks to @Pedro's answer for giving a clue on this).

To solve this, if you're using {{ request.path }} or {{ request.get_full_path }} from your template (or not setting it at all) to redirect to the same translated one, then you have to specify the next, slicing the language code as follows. The rest stays as the the docs say:

<input name="next" type="hidden" value="{{ request.get_full_path|slice:'3:' }}" />

I posted an answer explaining this in more detail and providing two functional examples.

like image 188
Caumons Avatar answered Sep 28 '22 00:09

Caumons


add translation.activate to your code:

from django.utils import translation

def set_language(request):
    next = request.REQUEST.get('next', None)
    if not next:
        next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = '/'
    response = http.HttpResponseRedirect(next)
    if request.method == 'GET':
        lang_code = request.GET.get('language', None)
        if lang_code and check_for_language(lang_code):
            if hasattr(request, 'session'):
                request.session['django_language'] = lang_code
            else:
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
            translation.activate(lang_code)
    return response
like image 25
Torsten Engelbrecht Avatar answered Sep 28 '22 00:09

Torsten Engelbrecht