【问题标题】:Django i18n_patterns: resolve() doesnt work as expectedDjango i18n 模式:resolve() 无法按预期工作
【发布时间】:2015-09-23 11:51:02
【问题描述】:

解决了here这个问题之后,还有一个问题:如果你在这里使用翻译url系统https://docs.djangoproject.com/en/1.8/topics/i18n/translation/你会看到你添加了urlpatterns += i18n_patterns(...)这样的模式。

问题是基本网址没有没有考虑语言,即:

  • resolve('/fr/produits/') 工作,
  • resolve('/produits/') 不起作用并引发 404。

如何解决?

这是我的网址:

urlpatterns = [
    url(r'^debug/?$', p_views.debug, name='debug'),
    url(r'^i18n/', include('django.conf.urls.i18n')),
    url(r'^login/(\w*)', p_views.login, name='login'),
    url(r'^admin/', include(admin_site.urls)),
    url(r'^public/(?P<path>.*)$',
        'django.views.static.serve',
        {'document_root': settings.MEDIA_ROOT},
        name='url_public'
        ),
]
urlpatterns += i18n_patterns(
    url(_(r'^produits/detail/(?P<slug>[a-zA-Z0-9-_]+)/$'),
        p_views.ProduitDetailView.as_view(), name='produits_detail'),
    url(_(r'^produits/'),
        p_views.IndexView.as_view(), name='produits_index'),
)

这是我制作的非常简单的 URL 测试器(对应于 /debug 视图):

def debug(req):

    def test(url):
        try:
            return u'<pre>{0} {1}</pre>'.format(url, resolve(url))
        except Resolver404:
            return u'<pre>{0} {1}</pre>'.format(url, 'None')

    response = HttpResponse()
    response.write(test('produits'))
    response.write(test('produits/'))
    response.write(test('/produits'))
    response.write(test('/produits/'))
    response.write(test('/fr/produits'))
    response.write(test('/fr/produits/'))
    response.write(test('/en/products/'))
    response.write(test('/sv/produkter/'))
    return response

这是http://localhost:8000/debug 页面:

produits None
produits/ None
/produits None
/produits/ None
/fr/produits None
/fr/produits/ ResolverMatch(func=produits.views.IndexView, args=(), kwargs={}, url_name=produits_index, app_name=None, namespaces=[])
/en/products/ None
/sv/produkter/ None

最后三行都应该返回 ResolverMatch(...),因为它们都是有效的 URL。

【问题讨论】:

  • @Sayse 谢谢,但我已经阅读了它,它并没有解决我的问题。我想做kinddof“反向翻译”从/sv/produkter//fr/produits/(看看它是一个有效的URL)
  • 是的,这就是我没有将其标记为重复的原因。我没能找到确切的解决方案,也没有时间帮助我害怕
  • 我已更新我的问题以显示更多详细信息。

标签: python django python-2.7 internationalization


【解决方案1】:

Django 的 url 解析器仅适用于当前语言。 因此,在尝试使用特定语言解析 url 之前,您需要切换语言,使用 translation.activate

为了解析 url,这意味着你必须事先知道语言,切换到它,然后才解析(基本上 localemiddleware 会为你做什么)。

为了反转 url,这意味着您可能应该使用其名称反转 url。您将以当前语言取回网址。我现在无法测试,但它应该像这样工作:

from django.utils import translation
translation.activate('fr')
reverse('produits_index')    # /fr/produits/
translation.activate('en')
reverse('produits_index')    # /en/products/

如果您确实设法获得了一个ResolverMatch 对象,那么您可以将 url 名称作为属性,方便地命名为 url_name

我希望它有所帮助,我有点不清楚你想要做什么。随时评论/编辑您的问题,我会尝试更新此答案。


Olivier Pons 更新


这是有效的解决方案:

这是我的工作解决方案,它接近光谱,但按我想要的方式工作:

# (!) resolve() use current language
#     -> try to guess language then activate BEFORE resolve()
lg_curr = translation.get_language()
lg_url = get_language_from_path(url) or lg_curr
translation.activate(lg_url)
try:
    resolve(url)
    req.session['url_back'] = url  # no error -> ok, remember this
except Resolver404:
    pass
translation.activate(lg_curr)

...然后,在成功注册/登录后,如果有 req.session['url_back'],那么我将其从会话中删除并对其进行重定向。

【讨论】:

  • 我已经添加了我的工作解决方案,所以我可以检查你的答案是否有效:)
  • 太棒了!正是我正在寻找并试图弄清楚一天的内容
猜你喜欢
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-19
  • 2019-12-24
  • 1970-01-01
相关资源
最近更新 更多