问题描述
我想用英文和西班牙语,并检测用户浏览器语言&重定向到正确的区域设置站点。
I want to deploy a website in english & spanish and detect the user browser language & redirect to the correct locale site.
我的网站是www.elmalabarista.com
My site is www.elmalabarista.com
我安装,但我发现语言未正确检测。
I install django-localeurl, but I discover that the language is not correctly detected.
这是我的中间件:
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',
)
但是,尽管事实上我的操作系统和浏览器设置是西班牙语。
But ALWAYS the site get to US despite the fact my OS & Browser setup is spanish.
LANGUAGES = (
('en', ugettext('English')),
('es', ugettext('Spanish')),
)
DEFAULT_LANGUAGE = 1
然后,我劫持了locale-url的中间件,并执行以下操作:
Then, I hack the middleware of locale-url and do this:
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()
然而,这种检测方式很好,但是将enurl重定向到es。所以是不可能的英文导航。
However, this detect fine the language but redirect the "en" urls to "es". So is impossible navigate in english.
更新:这是最后的代码(从卡尔迈耶的输入之后)与案例的修复的/:
UPDATE: This is the final code (after the input from Carl Meyer) with a fix for the case of "/":
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-localeurl的LocaleURLMiddleware现在直接支持HTTP Accept-Language作为备用,如果LOCALEURL_USE_ACCEPT_LANGUAGE设置为True。因此,OP的所需行为现在可以在没有编写自定义中间件的情况下使用)。
(Update: django-localeurl's LocaleURLMiddleware now directly supports HTTP Accept-Language as fallback, if LOCALEURL_USE_ACCEPT_LANGUAGE setting is True. So the OP's desired behavior is now available without writing a custom middleware).
启用Django的内置LocaleMiddleware和LocaleURLMiddleware是没有意义的。它们是作为相互排斥的替代方案,并且具有选择语言的不同逻辑。 Locale-url在锡上表示:locale由URL组件定义(因此不是Accept-Language头)。 Django的LocaleMiddleware将。启用两者只意味着无论哪一个人都获胜,这就是为什么你看到LocaleURLMiddleware的行为。
It does not make sense to have both Django's built-in LocaleMiddleware and LocaleURLMiddleware enabled. They are intended as mutually exclusive alternatives, and have different logic for choosing a language. Locale-url does what it says on the tin: the locale is defined by a URL component (thus not by the Accept-Language header). Django's LocaleMiddleware will choose the language based on a session value or cookie or Accept-Language header. Enabling both just means that whichever one comes last wins, which is why you're seeing the LocaleURLMiddleware behavior.
这听起来可能你想要一些两种混合,其中初始语言(访问网站的根URL?)是基于Accept-Language,然后由URL定义的?不完全清楚你想要什么行为,所以澄清这是第一步。那么你可能需要编写自己的LocaleMiddleware来实现这种行为。您首次尝试使用LocaleURLMiddleware时,始终使用Accept-Language代替URL中定义的内容。相反,您想要在if not locale:部分中进一步检查Accept-Language标题,该部分默认为settings.LANGUAGE_CODE。有些更像这样(未经测试的代码):
It sounds like maybe you want some kind of mix of the two, where the initial language (when visiting the root URL of the site?) is chosen based on Accept-Language, and thereafter defined by the URL? It's not entirely clear what behavior you want, so clarifying that is the first step. Then you'll probably need to write your own LocaleMiddleware that implements that behavior. Your first attempt at hacking LocaleURLMiddleware always uses Accept-Language in place of what's defined in the URL. Instead, you want to check the Accept-Language header further down, in the "if not locale:" section where it defaults to settings.LANGUAGE_CODE. Something more like this (untested 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()
这篇关于检测语言& django locale-url的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!