-->

Django1.4:通用的方式来设置模板语言链接与i18n_patterns工作?(Django1.

2019-07-29 01:59发布

我开始在Django 1.4新i18n_patterns玩。 基本上,我想为我的每一个支持的语言对我所有的模板头的语言链接。 我已经实现了我的头作为被包括在其他模板单独的模板。

有没有办法让我的头通用的,解决这个没有模板的上下文传递当前视图名称或电流网址? 我想这涉及到一个问题,怎样在一个通用的方法检索当前视图或URL从模板中。

顺便说一句,我发现,我以前用set_lang视图的方法来更改使用引荐将url_patterns被打破的变化时重定向到被称为视图,将其改回语言后激活的语言。

要与url_patterns在一个通用的方式使用的任何搞清楚常见的方法来设置模板语言链接帮助将不胜感激!

Answer 1:

基本上有两种不同的方法来设置语言。 您可以使用i18n_patterns为自动神奇地用语言代码前缀的网址,或者您可以使用django.views.i18n.set_language如果你的项目以更改用户会话的语言代码的值(或饼干,没有按“T有会话支持)。

值得一提的算法LocaleMiddleware用来确定语言:

  • 首先,它会在请求的URL的语言前缀。 当您使用在你的根URLconf中的i18n_patterns功能这只是执行。 关于语言的前缀,以及如何国际化URL模式的更多信息,URL模式:请参见国际化。

  • 如果做不到这一点,它会在当前用户的会话的django_language关键。

  • 如果做不到这一点,它会查找使用由LANGUAGE_COOKIE_NAME设置设置cookie的cookie.The名。 (默认名称为django_language。)

  • 如果做不到这一点,它看起来在接受语言HTTP标头。 此标头由浏览器发送和优先告诉服务器的语言(S)你愿意的话,井然有序。 Django的尝试在头每种语言,直到找到一个可用的翻译。

  • 如果做不到这一点,它使用全球LANGUAGE_CODE设置。

你可能会碰到的问题是,你不能使用set_language从一个已经被送达语言前缀,除非你明确传递一个网址重定向next的POST数据参数。 这是因为set_language将默认重定向到引用,其中包括以前的语言前缀, LocaleMiddleware随后将看到并服务于旧的语言内容(因为它会在URL中的语言前缀检查前django_language会话变量)。

举例来说,对于净度:

  1. 你的用户在/ EN /新闻/条/ 1000,点击其将发布的“语言= ES”的链接set_language

  2. set_language看到“语言= ES”,检查是否“ES”是可用的,然后设置“django_language”会话变量(或饼干)为“ES”

  3. 既然你没有设置“下一步”,它重定向到reqeuest.META [“HTTP_REFERRER”],这是/ EN /新闻/条/ 1000的值

  4. LocaleMiddleware ( 源 )认为,在URL中的“恩”字头,并激活成“en”语言,并设置request.LANGUAGE_CODE为“恩”

我看到了两个可能的解决方案:

  1. 写你自己的set_language视图(见原始出处这里 ),这将检查在引用(使用语言前缀django.utils.translation.get_language_from_path ),并重新导向到它之前将其更改为前缀的新选择语言。

  2. 使用JavaScript来完成相同的操作的客户端,并设置next POST参数。 真的,这是一种愚蠢的; 它很可能是简单,只需使用JavaScript来动态前置与用户的首选语言代码的所有URL,而忘记了set_language干脆。

看来,这个新set_language观点也许应该是Django的默认行为。 有提出了票 ,其中包括建议的实施,但并没有真正说明问题,并随后关闭。 我建议打开一个新的票与你的使用情况,造成现有问题的一个更好的描述set_language实现,你的建议的解决方案。



Answer 2:

已经使用Django 1.7今天有同样的问题,我设计这个解决方案 - 不是很干,但它似乎工作确定(和我所有的测试都通过,所以...)。 而不是使用内置set_language观点,我抄了一遍,并做一个小小的调整 - 这里的结果:

def set_language(request):
"""
Redirect to a given url while setting the chosen language in the
session or cookie. The url and the language code need to be
specified in the request parameters.

Since this view changes how the user will see the rest of the site, it must
only be accessed as a POST request. If called as a GET request, it will
redirect to the page in the request (the 'next' parameter) without changing
any state.
"""
next = request.POST.get('next', request.GET.get('next'))
if not is_safe_url(url=next, host=request.get_host()):
    next = request.META.get('HTTP_REFERER')
    if not is_safe_url(url=next, host=request.get_host()):
        next = '/'
lang_code = request.POST.get('language', None)
# Start changed part
next = urlparse(next).path  # Failsafe when next is take from HTTP_REFERER
# We need to be able to filter out the language prefix from the next URL
current_language = translation.get_language_from_path(next)
translation.activate(current_language)
next_data = resolve(next)
translation.activate(lang_code)  # this should ensure we get the right URL for the next page
next = reverse(next_data.view_name, args=next_data.args, kwargs=next_data.kwargs)
# End changed part
response = http.HttpResponseRedirect(next)
if request.method == 'POST':
    if lang_code and check_for_language(lang_code):
        if hasattr(request, 'session'):
            request.session[LANGUAGE_SESSION_KEY] = lang_code
        else:
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
                                max_age=settings.LANGUAGE_COOKIE_AGE,
                                path=settings.LANGUAGE_COOKIE_PATH,
                                domain=settings.LANGUAGE_COOKIE_DOMAIN)
return response

概括起来讲,我决心()为下查看参数,然后将数据传递到倒车档()启动新的语言之后。 希望这可以帮助。



Answer 3:

其实,没有必要你的看法拨弄。 Django中有一个方便的片标记,这样你就可以只使用{{ request.path|slice:'3:' }}为您的链接网址。 这LOPS语言代码前缀关闭,因此该语言由set_lang功能设置。



Answer 4:

我道歉了长时间的延迟。 谢谢大家的答案。

首先要对克里斯两种解决方案选项评论:无论是定制set_language和JavaScript是好为宗旨作为URL模式的整体美感正在SEO友好。

此外,只需替换URL前缀语言不能被视为完整的解决方案基于URLPATTERN网址作为整个URL可能是翻译过。 例如: /en/profile/英语和/fr/profil/法语。 为了解决一个需要捕捉viewfunc和参数,以便扭转它为不同的语言这样的问题。

幸运的是,我的项目不使用翻译的网址,现在,我采取了以下方法。

  1. 添加django.core.context_processors.requestTEMPLATE_CONTEXT_PROCESSORS ,这样的要求是在模板渲染上下文可用。

  2. 使用RequestContext视图中显示视图时。 这始终是独立的话题,我的情况。

  3. 写一个很简单的templatetag需要的背景和一个带有参数的语言代码,在给定的语言返回当前URL。 它基本上可以确保当前的URL具有有效的语言代码前缀,只是返回另一个字符串,它是同当前的URL替换为语言代码。

例如:

from django import template
register = template.Library()

@register.simple_tag(takes_context=True)
def get_current_url_for_lang(context, lang_code):
    request=context.get('request',False)
    if not request:
        return None

    request=context['request']
    curr_url=request.path
    if len(curr_url) < 4 or curr_url[0] != '/' or curr_url[3] != '/':
        return curr_url

    if context.get('LANGUAGES',False):
        codes = []
        for code,name in context['LANGUAGES']:
            codes.append(code)

        curr_langcode = curr_url[1:3]
        if lang_code not in codes or curr_langcode not in codes:
            return curr_url

    changed_url = '/'+lang_code+curr_url[3:]
    return changed_url

此外,如果一个人不喜欢注入完整的请求的来龙去脉这将是相当简单的写自己的context_processor简单地推动request.path作为current_url_path的实例,并使用在而不是你的templatetag

您的意见,欢迎一如既往!



文章来源: Django1.4: Generic way to set language links in template to work with i18n_patterns?