Django: i18n - 更改语言

13 投票
5 回答
26308 浏览
提问于 2025-04-16 14:45

我安装了 model_translation、rosetta 和 locale_url,但语言切换不生效。

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

我用来切换语言的视图:

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

在模板中的内容:

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

我的中间件设置:

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

但是语言切换还是不行。如果我打开链接 http://localhost/uk/ 进行语言切换,但当我切换到另一个页面时,语言又回到了默认语言。我该怎么办?

5 个回答

3

根据Torsten提供的代码,你的链接不会改变,因为'next'总是类似于 */ru/*other/urls的格式。它永远不会是None(其实上面那两个if条件是没用的)。你的语言会因为set_cookietranslation.activate而改变。但是当你在网站上点击其他任何英文链接时,语言又会变回ru。

你可以尝试使用django的set_language内置视图,具体可以参考这里,或者通过尝试一些替换操作来处理'next'字符串。

6

我遇到过同样的问题,原因是next参数前面加上了旧的语言代码,这样就导致新的语言代码无法生效。(感谢@Pedro的回答给了我一些提示)。

要解决这个问题,如果你在模板中使用{{ request.path }}{{ request.get_full_path }}(或者根本不设置)来重定向到同样的翻译版本,那么你需要在指定next时,把语言代码去掉,具体做法如下。其他部分就按照文档中的说明来处理:

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

我在这里发布了一个回答,详细解释了这个问题,并提供了两个可用的示例。

8

在你的代码里加上 translation.activate:

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

撰写回答