【问题标题】:Detect the language & django locale-url检测语言和 django locale-url
【发布时间】:2010-12-04 10:06:33
【问题描述】:

我想部署一个英文和西班牙文网站,并检测用户浏览器语言并重定向到正确的区域设置网站。

我的网站是 www.elmalabarista.com

我安装了django-localeurl,但发现语言检测不正确。

这是我的中间件:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.locale.LocaleMiddleware',    
    'multilingual.middleware.DefaultLanguageMiddleware',
    'middleware.feedburner.FeedburnerMiddleware',
    'lib.threadlocals.ThreadLocalsMiddleware',
    'middleware.url.UrlMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'maintenancemode.middleware.MaintenanceModeMiddleware',
    'middleware.redirect.RedirectMiddleware',
    'openidconsumer.middleware.OpenIDMiddleware',
    'django.middleware.doc.XViewMiddleware',
    'middleware.ajax_errors.AjaxMiddleware',
    'pingback.middleware.PingbackMiddleware',
    'localeurl.middleware.LocaleURLMiddleware', 
    'multilingual.flatpages.middleware.FlatpageFallbackMiddleware',
    'django.middleware.common.CommonMiddleware',
)

但尽管我的操作系统和浏览器设置是西班牙语,但网站总是会到达美国。

LANGUAGES = (
    ('en', ugettext('English')),  
    ('es', ugettext('Spanish')),
)
DEFAULT_LANGUAGE = 1

然后,我破解 locale-url 的中间件并这样做:

def process_request(self, request):
    locale, path = self.split_locale_from_request(request)
    if request.META.has_key('HTTP_ACCEPT_LANGUAGE'):
        locale = utils.supported_language(request.META['HTTP_ACCEPT_LANGUAGE'].split(',')[0])
    locale_path = utils.locale_path(path, locale)

    if locale_path != request.path_info:
        if request.META.get("QUERY_STRING", ""):
            locale_path = "%s?%s" % (locale_path,
                    request.META['QUERY_STRING'])
        return HttpResponseRedirect(locale_path)
    request.path_info = path
    if not locale:
        locale = settings.LANGUAGE_CODE
    translation.activate(locale)
    request.LANGUAGE_CODE = translation.get_language()

但是,这可以检测到正确的语言,但会将“en”网址重定向到“es”。所以用英文导航是不可能的。

更新:这是最终代码(在 Carl Meyer 的输入之后)修复了“/”的情况:

def process_request(self, request):
    locale, path = self.split_locale_from_request(request)
    if (not locale) or (locale==''):
        if request.META.has_key('HTTP_ACCEPT_LANGUAGE'):
            locale = utils.supported_language(request.META['HTTP_ACCEPT_LANGUAGE'].split(',')[0])
        else:
            locale = settings.LANGUAGE_CODE
    locale_path = utils.locale_path(path, locale)
    if locale_path != request.path_info:
        if request.META.get("QUERY_STRING", ""):
            locale_path = "%s?%s" % (locale_path, request.META['QUERY_STRING'])
        return HttpResponseRedirect(locale_path)
    request.path_info = path
    translation.activate(locale)
    request.LANGUAGE_CODE = translation.get_language()

【问题讨论】:

    标签: django localization django-middleware


    【解决方案1】:

    更新:如果 LOCALEURL_USE_ACCEPT_LANGUAGE 设置为 True,则 django-localeurl 的 LocaleURLMiddleware 现在直接支持 HTTP Accept-Language 作为后备。因此,现在无需编写自定义中间件即可获得 OP 所需的行为)。

    同时启用 Django 的内置 LocaleMiddleware 和 LocaleURLMiddleware 是没有意义的。它们旨在作为相互排斥的替代方案,并且具有不同的语言选择逻辑。 Locale-url 就像它在锡上所说的那样:语言环境由 URL 组件定义(因此不是由 Accept-Language 标头定义)。 Django 的 LocaleMiddleware 将 choose the language based on a session value or cookie or Accept-Language header。启用两者仅意味着最后一个获胜,这就是您看到 LocaleURLMiddleware 行为的原因。

    听起来您可能想要两者的某种混合,其中初始语言(访问站点的根 URL 时?)是根据接受语言选择的,然后由 URL 定义?尚不清楚您想要什么行为,因此第一步是澄清。然后您可能需要编写自己的 LocaleMiddleware 来实现该行为。您第一次尝试破解 LocaleURLMiddleware 总是使用 Accept-Language 代替 URL 中定义的内容。相反,您想在“if not locale:”部分进一步检查 Accept-Language 标头,该部分默认为 settings.LANGUAGE_CODE。更像这样的东西(未经测试的代码):

    def process_request(self, request):
        locale, path = self.split_locale_from_request(request)
        locale_path = utils.locale_path(path, locale)
    
        if locale_path != request.path_info:
            if request.META.get("QUERY_STRING", ""):
                locale_path = "%s?%s" % (locale_path, request.META['QUERY_STRING'])
            return HttpResponseRedirect(locale_path)
        request.path_info = path
        if not locale:
            if request.META.has_key('HTTP_ACCEPT_LANGUAGE'):
                locale = utils.supported_language(request.META['HTTP_ACCEPT_LANGUAGE'].split(',')[0])
            else:
                locale = settings.LANGUAGE_CODE
        translation.activate(locale)
        request.LANGUAGE_CODE = translation.get_language()
    

    【讨论】:

    • 是的,我想要混合 btoh:第一次从 Accept-Language 获取默认语言,但之后使用 URL 样式。我不知道将它存储在 cookie 中是否也很重要......但我认为更好的行为就是你所描述的。
    • 感谢您的意见。我放了您的代码,但对“/”的情况进行了修复
    • 这对我来说是错误的。我需要更改哪个文件。它给出了关于语言环境的错误,路径 = self.split_locale_from_request(request)
    • @ha22109 请参阅此答案顶部的注释。升级到最新的 django-localeurl 版本(1.4)并将 LOCALEURL_USE_ACCEPT_LANGUAGE 设置为 True,您根本不需要编写任何自定义中间件。
    • 我根据您的标题更改了我的 settings.py 文件并安装了最新的 localeurl 版本(1.4)。但是当我更改我的浏览器语言环境时,我的网站并没有改变,只有登录部分正在改变仅在 django-admin 中定义。知道为什么我看不到我的翻译。我需要设置 local_path
    【解决方案2】:

    我也需要这种行为。 您现在是仅使用自定义中间件来获取语言,还是仍在使用 LocaleURLMiddleware 和 LocaleMiddleware 与上述代码中的中间件?

    【讨论】:

    【解决方案3】:

    真的应该是这样的:

    可以按优先顺序接受多种语言

    def process_request(self, request):
        locale, path = utils.strip_path(request.path_info)
        if (not locale) or (locale==''):
            if request.META.has_key('HTTP_ACCEPT_LANGUAGE'):
            l = [x.strip()[:2] for x in request.META['HTTP_ACCEPT_LANGUAGE'].split(',')]
            for lang_code in l:
                    locale = utils.supported_language(lang_code)
                    if locale:
              break
            else:
                locale = settings.LANGUAGE_CODE
        locale_path = utils.locale_path(path, locale)
        if locale_path != request.path_info:
            if request.META.get("QUERY_STRING", ""):
                locale_path = "%s?%s" % (locale_path,
                        request.META['QUERY_STRING'])
            return HttpResponseRedirect(locale_path)
        request.path_info = path
        if not locale:
            try:
                locale = request.LANGUAGE_CODE
            except AttributeError:
                locale = settings.LANGUAGE_CODE
        translation.activate(locale)
        request.LANGUAGE_CODE = translation.get_language()
    

    【讨论】:

      猜你喜欢
      • 2015-03-04
      • 1970-01-01
      • 2011-03-12
      • 2014-12-05
      • 2015-08-14
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多