2015-09-23 86 views
1

解決了這個問題here之後,還有另外一個問題:如果您在這裏使用翻譯url系統https://docs.djangoproject.com/en/1.8/topics/i18n/translation/,您會看到您添加了像urlpatterns += i18n_patterns(...)這樣的模式。Django i18n_patterns:resolve()不按預期方式工作

的問題是,基本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'), 
) 

而這裏的非常簡單的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。

+0

相關:[Django i18n默認語言沒有路徑前綴](http://stackoverflow.com/q/13636604/1324033) – Sayse

+0

@Sayse謝謝,但我已經閱讀它,它不能解決我的問題。我想從'/ sv/produkter /'轉到'/ fr/produits /'(看到它是一個有效的URL),做一些「反向翻譯」 –

+0

這就是爲什麼我沒有把它標記爲重複的。我沒有設法找到一個確切的分辨率,沒有時間來幫助我害怕 – Sayse

回答

2

Django的url解析器僅適用於當前語言。 因此,在嘗試使用特定語言解決網址之前,您需要先切換語言,然後使用translation.activate

爲了解決url,這意味着你必須事先知道該語言,切換到它,然後才解決(基本上localemiddleware會爲你做什麼)。

爲了反轉網址,這意味着您應該使用其名稱來反轉網址。你會用當前語言找回網址。我現在不能測試,但它應該像這樣工作:

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龐斯


這裏的工作解決方案:

這裏是我工作的解決方案,這是接近spectras,但工程我想要的方式:

# (!) 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']然後我從會話中刪除它並對其進行重定向。

+1

我已經添加了我的工作解決方案,因此我可以檢查您的答案爲有效**':)'** –

+0

太棒了!正是我正在尋找,並試圖找出一天現在 – Vlad