2015-02-23 50 views
1

我已正确安装国际化。在Django切换语言与翻译的URL重定向

它的作品中包含的网址:

/en/bookings/ #English 
/es/reservas/ #Spanish 

在主页的语言切换工作也没关系。

- 什么问题?

当我在翻译的页面中更改语言(如/ en/bookings /)时,如果将语言翻译成西班牙语,我将重定向到/ zh/bookings/。

如果我更改前缀(like this answer),重定向转到/ es/bookings /不存在。

我不想被重定向到主页。

- 我喜欢什么?

如果我在/ en/bookings /并切换到西班牙语,我希望被重定向到/ es/reservas /,以用于所有翻译的URL。

什么是最好的方法?

谢谢。

回答

1

当我有同样的问题,我实现了一个自定义模板标签(current_url),鉴于上下文的请求,重新呈现为活动语言的网址:

{% load custom_tags %} 
<ul> 
{% get_language_info_list for LANGUAGES as languages %} 
{% for language in languages %} 
    {# IMPORTANT! enclose the 'current_url' tag in a 'language' block #} 
    {% language language.code %} 
     <li {% if language.code == LANGUAGE_CODE %}class="active"{% endif %}> 
      <a href="{% current_url %}">{{ language.name_local }}</a> 
     </li> 
    {% endlanguage %} 
{% endfor %} 
</ul> 

下面是代码自定义标签(custom_tags.py):

import six 
import sys 
from django.template import Node, TemplateSyntaxError, Library 
from django.conf import settings 

register = Library() 

class CurrentURLNode(Node): 

    def __init__(self, asvar=None): 
     self.asvar = asvar 

    def render(self, context): 
     request = context['request'] 
     from django.core.urlresolvers import reverse, NoReverseMatch 
     url = '' 
     try: 
      url = reverse(request.resolver_match.view_name, args=request.resolver_match.args, kwargs=request.resolver_match.kwargs, current_app=context.current_app) 
     except NoReverseMatch: 
      exc_info = sys.exc_info() 
      if settings.SETTINGS_MODULE: 
       project_name = settings.SETTINGS_MODULE.split('.')[0] 
       try: 
        url = reverse(project_name + '.' + request.resolver_match.view_name, 
          args=request.resolver_match.args, kwargs=request.resolver_match.kwargs, 
          current_app=context.current_app) 
       except NoReverseMatch: 
        if self.asvar is None:      
         six.reraise(*exc_info) 
      else: 
       if self.asvar is None: 
        raise 

     if self.asvar: 
      context[self.asvar] = url 
      return '' 
     else: 
      return url 

@register.tag 
def current_url(parser, token): 
    bits = token.split_contents() 
    bits = bits[1:] 
    asvar = None 
    if len(bits) >= 2 and bits[-2] == 'as': 
     asvar = bits[-1] 
     bits = bits[:-2] 
    if len(bits): 
     raise TemplateSyntaxError("Unexpected arguments to current_url tag") 
    return CurrentURLNode(asvar) 

没有必要使用'set_language'django视图。无需发出POST请求来更改活动语言。只有html archiant将所有国际化内容链接在一起,对SEO来说更好。

1

我有类似的问题,所以我发送我的决议,以节省您的时间。

主(urls.py)

from django.conf.urls import include, url 
from django.conf.urls.i18n import i18n_patterns 

urlpatterns = [ 
    url(r'^i18n/', include('django.conf.urls.i18n')), 
] 

urlpatterns += i18n_patterns(
    url(r'^', include('index.urls', namespace='index')), 
) 

(index.urls.py)

from django.conf.urls import url 
from django.views.generic import TemplateView 
from django.utils.translation import ugettext_lazy as _ 


urlpatterns = [ 
    url(r'^$', TemplateView.as_view(template_name='index/index.html'), name='index'), 
    url(_(r'^python-programming/$'), TemplateView.as_view(template_name='index/new_page.html'), 
     name='new_page'), 
] 

创建模板标签中,我们支持所有语言返回当前位置的URL(index.templatetags .helper_tags.py)

from django.template import Library 
from django.core.urlresolvers import resolve, reverse 
from django.utils.translation import activate, get_language 

register = Library() 


@register.simple_tag(takes_context=True) 
def change_lang(context, lang=None, *args, **kwargs): 
    """ 
    Get active page's url by a specified language 
    Usage: {% change_lang 'en' %} 
    """ 

    path = context['request'].path 
    url_parts = resolve(path) 

    url = path 
    cur_language = get_language() 
    try: 
     activate(lang) 
     url = reverse(url_parts.view_name, kwargs=url_parts.kwargs) 
    finally: 
     activate(cur_language) 

    return "%s" % url 

创建中间件来更改站点语言,当用户点击alt ernative连结此子网站,但在不同的语言 (middleware.py)

from django.utils import translation 
from django.conf import settings 
from django.utils.deprecation import MiddlewareMixin 


class LangBasedOnUrlMiddleware(MiddlewareMixin): 

    @staticmethod 
    def process_request(request): 

     if hasattr(request, 'session'): 
      active_session_lang = request.session.get(translation.LANGUAGE_SESSION_KEY) 

      if active_session_lang == request.LANGUAGE_CODE: 
       return 

      if any(request.LANGUAGE_CODE in language for language in settings.LANGUAGES): 
       translation.activate(request.LANGUAGE_CODE) 
       request.session[translation.LANGUAGE_SESSION_KEY] = request.LANGUAGE_CODE 

它添加到(设置。PY)刚过模板LocaleMiddleware

MIDDLEWARE = [ 
    'django.middleware.security.SecurityMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.locale.LocaleMiddleware', 
    'our_app.middleware.LangBasedOnUrlMiddleware', 
] 

使用范例:

{% load i18n %} 
{% load helper_tags %} 
    {% get_available_languages as languages %} 
    {% for lang_code, lang_name in languages %} 
     <a href="{{ request.scheme }}://{{ request.META.HTTP_HOST }}{% change_lang lang_code %}"> 
    {% endfor %}