Django i18n_patterns:resolve()不按预期工作 [英] Django i18n_patterns: resolve() doesnt work as expected

查看:102
本文介绍了Django i18n_patterns:resolve()不按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



问题是基础url 没有的语言不是用于帐户ie:




  • 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'产品/细节/(?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'),

pre>

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

$ b

  def debug(req):

def test(url):
try :
return u'< pre> {0} {1}< / pre>'。format(url,resolve(url))
除了Resolv er404:
return u'< pre> {0} {1}< / pre>'格式(url,'None')

response = HttpResponse()
response.write(test('produits'))
response.write(test('produits /'))
response.write(test('/ produits'))
响应。 write(test('/ produits /'))
response.write(test('/ fr / produits'))
response.write(test('/ fr / produits /'))
response.write(test('/ en / products /'))
response.write(test('/ sv / produkter /'))
返回响应

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

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

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

解决方案

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



要解决url,这意味着你必须事先知道这个语言,切换到它,然后才能解决(基本上是本地中间件将为你做什么)。



为了反转url,意味着您应该使用其名称来反转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()使用当前语言
# - >尝试猜测语言然后激活BEFORE resolve()
lg_curr = translation.get_language()
lg_url = get_language_from_path(url)或lg_curr
translation.activate(lg_url)
try:
resolve(url)
req.session ['url_back'] = url#no error - >好的,记住这个
除了Resolver404:
pass
translation.activate(lg_curr)

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


After solving this problem here, there's another one: if you use the translation url system here https://docs.djangoproject.com/en/1.8/topics/i18n/translation/ you will see you add patterns like urlpatterns += i18n_patterns(...).

The problem is that the base url without the language is not taken in account ie:

  • resolve('/fr/produits/') works,
  • but resolve('/produits/') doesnt work and raises 404.

How to solve this?

Here are my urls:

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'),
)

And here's the very simple URL-tester I've made (which corresponds to the /debug view):

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

Here's the http://localhost:8000/debug page:

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

The three lastest lines should all return ResolverMatch(...) because they are all valid URLs.

解决方案

Django's url resolvers only work on current language. So you will need to switch language before attempting to solve an url in a specific language, using translation.activate.

For resolving the url, that means you must know the language beforehand, switch to it and only then resolve (basically what the localemiddleware will do for you).

For reversing the url, that means you should probably reverse the url using its name. You'll get back the url in current language. I cannot test right now, but it should work like this:

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

If you did manage to get a ResolverMatch object, you have the url name as an attribute on it, conveniently named url_name.

I hope it helps, I am a bit unclear as to what you are trying to do. Feel free to comment/edit your question and I'll try to update this answer.


Update by Olivier Pons


Here's the working solution:

here's my working solution, which is close to spectras, but works the way I wanted:

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

...and then later on, after successful registration/login, if there's a req.session['url_back'] then I remove it from session and make a redirect on it.

这篇关于Django i18n_patterns:resolve()不按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆