Django i18n_patterns:resolve() 无法按预期工作

Oli*_*ons 4 python django internationalization python-2.7

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

问题是不考虑不带语言的基本 url,即:

  • 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'),
)
Run Code Online (Sandbox Code Playgroud)

这是我制作的非常简单的 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
Run Code Online (Sandbox Code Playgroud)

这是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
Run Code Online (Sandbox Code Playgroud)

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

spe*_*ras 5

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/
Run Code Online (Sandbox Code Playgroud)

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

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


奥利维尔·庞斯更新


这是工作解决方案:

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

# (!) 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)
Run Code Online (Sandbox Code Playgroud)

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