Определить язык и местный URL-адрес Django - PullRequest
3 голосов
/ 07 октября 2009

Я хочу развернуть веб-сайт на английском и испанском языках, определить язык браузера пользователя и перенаправить на нужный сайт.

Мой сайт 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()

Однако, это хорошо определяет язык, но перенаправляет URL "en" на "es". Так что невозможно ориентироваться на английском.

ОБНОВЛЕНИЕ: Это окончательный код (после ввода Карла Мейера ) с исправлением для случая "/":

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()

Ответы [ 3 ]

11 голосов
/ 07 октября 2009

( Обновление : LocaleURLMiddleware django-localeurl теперь напрямую поддерживает HTTP Accept-Language в качестве запасного, если для параметра LOCALEURL_USE_ACCEPT_LANGUAGE установлено значение True. Таким образом, желаемое поведение OP теперь доступно без записи пользовательского промежуточного программного обеспечения).

Нет смысла включать встроенные в Django LocaleMiddleware и LocaleURLMiddleware. Они предназначены как взаимоисключающие альтернативы и имеют различную логику для выбора языка. Locale-url делает то, что говорит на банке: локаль определяется компонентом URL (то есть не заголовком Accept-Language). LocaleMiddleware от Django выберет язык на основе значения сеанса, файла cookie или заголовка Accept-Language . Включение обоих означает только то, что какой-либо из них выйдет последним, именно поэтому вы наблюдаете поведение LocaleURLMiddleware.

Звучит так, как будто вы хотите какую-то смесь из двух, где исходный язык (при посещении корневого URL-адреса сайта?) Выбирается на основе Accept-Language, а затем определяется URL-адресом? Не совсем понятно, какое поведение вы хотите, поэтому уточнение - это первый шаг. Тогда вам, вероятно, нужно написать свое собственное LocaleMiddleware, которое реализует это поведение. Ваша первая попытка взлома LocaleURLMiddleware всегда использует Accept-Language вместо того, что определено в URL. Вместо этого вы хотите проверить заголовок 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()
1 голос
/ 24 февраля 2010

Мне тоже нужно такое поведение. Вы используете только свое специальное промежуточное программное обеспечение для получения языка или вы все еще используете LocaleURLMiddleware и LocaleMiddleware в сочетании с промежуточным программным обеспечением в приведенном выше коде?

0 голосов
/ 10 марта 2010

действительно так и должно быть:

В порядке предпочтения может быть принято несколько языков

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...