检测语言和django 语言环境-url
我想部署一个英语和英语网站西班牙语并检测用户浏览器语言&重定向到正确的语言环境站点。
我的网站是 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”url 重定向到“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()
I want to deploy a website in English & Spanish and detect the user browser language & redirect to the correct locale site.
My site is www.elmalabarista.com
I install django-localeurl, but I discover that the language is not correctly detected.
This are my middlewares:
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
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()
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
(更新:如果 LOCALEURL_USE_ACCEPT_LANGUAGE 设置为 True,django-localeurl 的 LocaleURLMiddleware 现在直接支持 HTTP Accept-Language 作为后备。因此现在无需编写自定义中间件即可获得 OP 所需的行为)。
同时启用 Django 内置的 LocaleMiddleware 和 LocaleURLMiddleware 是没有意义的。它们旨在作为相互排斥的替代方案,并且在选择语言时具有不同的逻辑。 Locale-url 的作用正如其表面所言:区域设置由 URL 组件定义(因此不是由 Accept-Language 标头定义)。 Django 的 LocaleMiddleware 将 根据会话值或 cookie 或 Accept-Language 标头选择语言。启用两者仅意味着最后一个获胜,这就是您看到 LocaleURLMiddleware 行为的原因。
听起来也许您想要两者的某种混合,其中初始语言(当访问站点的根 URL 时?)是基于 Accept-Language 选择的,然后由 URL 定义?目前尚不完全清楚您想要什么行为,因此澄清这一点是第一步。然后您可能需要编写自己的 LocaleMiddleware 来实现该行为。您第一次尝试破解 LocaleURLMiddleware 时总是使用 Accept-Language 来代替 URL 中定义的内容。相反,您需要在“if not locale:”部分中进一步检查 Accept-Language 标头,其中默认为 settings.LANGUAGE_CODE。更像这样(未经测试的代码):
(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).
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.
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):
我也需要这种行为。
您现在只使用自定义中间件来获取语言,还是仍在使用 LocaleURLMiddleware 和 LocaleMiddleware 与上面代码中的中间件结合使用?
i would need this behaviour too.
are you using only your custom middleware now to get the language or are you still using the LocaleURLMiddleware and the LocaleMiddleware in combination with the middleware in the code above?
实际上应该是这样的:
可以按优先顺序接受多种语言
really it should be like this:
There can be multiple languages accepted by order of preference
您可以检测用户浏览器语言,然后通过设置 LocaleMiddleware 到 中间件在 SessionMiddleware 和 CommonMiddleware 如下所示。 *您可以查看我的回答解释如何用英语和法语详细说明:
You can detect the user browser language, then redirect to the correct locale site by setting LocaleMiddleware to MIDDLEWARE between SessionMiddleware and CommonMiddleware as shown below. *You can see my answer explaining how to do that in English and French in details: