2011-08-31 20 views
3

我知道Django首先從瀏覽器標題中爲網站選擇默認語言,然後使用該語言顯示頁面,如果它匹配來自設置的可能選擇。Django語言環境如何在視圖之間工作

我想要做的是更改&在用戶登錄後設置該語言。我已經爲用戶提供了默認設置的表單。登錄後,從defaultSettings型號中挑選默認語言。而我做的是:

d = DefaultSettings.objects.filter(user = request.user) 
if len(d) > 0 and d[0].has_default_language: 
    from django.utils import translation  
    translation.activate(d[0].default_language) 
    request.LANGUAGE_CODE = translation.get_language() 

和我所看到的是「錯誤的」語言頁面。

這讓我問 - 爲什麼?我沒有自己編寫代碼。我是從下面的例子

由於所有這些例子修改請求/響應在middleware - 我真的需要做的一樣嗎?請求Django重置請求之間的語言,並嘗試在每次請求後再次「猜測」它?

爲什麼我的設置方式一次沒有工作?

艾倫

更新(從辛德里古德蒙德森)第一響應後:

if form.is_valid (): 
     if not redirect_to or '//' in redirect_to or ' ' in redirect_to: 
      redirect_to = settings.LOGIN_REDIRECT_URL 
     if not form.cleaned_data [ 'remember_me' ]: 
      request.session.set_expiry (0) 
     from django.contrib.auth import login 
     login (request, form.get_user ()) 
     if request.session.test_cookie_worked (): 
      request.session.delete_test_cookie () 
     set_lang_to_user_default_language(request) 
     response = HttpResponseRedirect (redirect_to) 
     d = DefaultSettings.objects.filter(user = request.user) 
     if len(d) > 0 and d[0].has_default_language:     
      from django.utils import translation 
      translation.activate(d[0].default_language) 
      logger.debug(translation.get_language()) 
      request.LANGUAGE_CODE = translation.get_language()     
      if hasattr(request, 'session'): 
       logger.debug('set django_language') 
       request.session['django_language'] = translation.get_language() 
      else: 
       logger.debug('set response cookie') 
       response.set_cookie(settings.LANGUAGE_COOKIE_NAME, translation.get_language()) 
     return response 

當我檢查日誌,我看到:

DEBUG 2011-09-01 09:08:13,379 et 
DEBUG 2011-09-01 09:08:13,379 set django_language 

但是,當我在一個視圖檢查模板,我在那裏打印出{{ LANGUAGE_CODE }},那麼它顯示'en'不是'et'

UPDATE2:

處理這一觀點後實際發生的事情是: 第1頁,其中這個觀點重定向到{{LANGUAGE_CODE}}是「恩」的內容是英語 第2頁,我第一次{{ LANGUAGE_CODE }}之後走的是「恩」但內容在愛沙尼亞語 第二頁,我在第二個{{LANGUAGE_CODE}}之後去的是'en',並且內容再次以英文顯示,並保持英文。

所以它看起來像我必須創建我自己的middleware保持頁面在「正確的」語言......我的問題是 - 爲什麼?

UPDATE3:我的語言設置是這樣的:

LANGUAGES = (
      ('et', gettext('Estonian')), 
      ('en', gettext('English')), 
      ('ru', gettext('Russian')), 
      ('lv', gettext('Latvian')), 
      ('lt', gettext('Lithuanian')), 
      ('fi', gettext('Finnish')), 
      ) 

但經過進一步調查,我想我找到了一個解決方法。我在此項目中使用django-cms,並關閉了cms.middleware.multilingual.MultilingualURLMiddleware,並遇到了上述問題。當我再次打開它時,一切正常 - 但它工作得很好,因爲middleware已打開,它將所需參數放入每個響應中。

我最初問我的問題是 - 它是如何工作的。之後我問了問題。現在,我認爲,問題是 - 是否真的必須爲每個request/response設置語言,如middleware所做的那樣,並且與示例middlewares一樣嗎?

+0

登錄後第一頁的request.session ['django_language']'的價值是什麼? –

+0

'en' - 它從我的瀏覽器中擷取它 - 因爲我的瀏覽器語言是英語。 –

+0

@Zayatss;你的'settings.LANGUAGES'如何佈置?如果'et'不在那裏,django會回退到使用瀏覽器的語言。 'settings.LANGUAGES'應該是元組的元組,'((lang_code,lang_name),...)'請參閱[this](https://code.djangoproject.com/browser/django/trunk/django/utils/翻譯/ trans_real.py#L366)爲更好的解釋... –

回答

4

建議/回答:

我上也有一些怪異的行爲!因爲我忘記添加「LocaleMiddleware」,要仔細檢查它的存在,爲了說明這是怎麼了我的「MIDDLEWARE_CLASSES」的模樣:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.locale.LocaleMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
) 

中間件負責處理您的請求和響應,並添加語言!

此外,還要保留「SindriGuðmundsson」的代碼,該代碼正在改變lang!

編輯

得遠一點!如果我們看看LocaleMiddleware:

def process_request(self, request): 
    language = translation.get_language_from_request(request) 
    translation.activate(language) 
    request.LANGUAGE_CODE = translation.get_language() 

所以問題是!爲什麼Django需要它?!答案是:因爲如果您使用{{LANGUAGE_CODE}},它正在從REQUEST中讀取數據,所以LANGUAGE_CODE必須在請求中!除此以外 !它不會返回它!所以這就是爲什麼這個中間件存在! 檢查出來的評論,在中間件的實際源代碼:

""" 
This is a very simple middleware that parses a request 
and decides what translation object to install in the current 
thread context. This allows pages to be dynamically 
translated to the language the user desires (if the language 
is available, of course). 
""" 

同時檢查文檔:https://docs.djangoproject.com/en/1.3/topics/i18n/deployment/#how-django-discovers-language-preference

+0

你是絕對正確的 - 我刪除了中間件的原因,如果我沒有記錯系統開始拋出一些消息,當我在中間件類以及django dms多語言網址中間件。 –

+0

所以,只要把它放回去,並檢查它是否工作!如果是這樣,我會很高興在這裏從它=) –

+0

事情是 - 我不想要它,問題是 - 爲什麼我需要這樣的中間件,爲什麼它不只是通過設置cookie的工作。但是,從西蒙斯的回答和從你的遠程看來,需要一箇中間件來爲每一個請求做到這一點,這就是django的工作原理。 –

1

退房set_languagedjango.views.i18n 33行你必須設置的語言代碼在會話的用戶:

if hasattr(request, 'session'): 
    request.session['django_language'] = lang_code 
else: 
    response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code) 
+1

也不起作用。生病添加問題更新與我使用的代碼。 –

0

Django的CMS使用request.LANGUAGE_CODE來確定使用哪種語言,如果你不」 t特別要求您的GET或POST參數中使用某種語言。

Django CMS使用中間件MultilingualURLMiddleware來設置request.LANGUAGE_CODE。

該中間件首先在url中查找語言前綴,然後查找會話密鑰的語言。

這意味着如果您想要另一種語言,您可以在會話變量中設置一次,但MultilingualURLMiddleware仍然會在每個請求中設置request.LANGUAGE_CODE。

+0

MMyeah,所以您所說的是,因爲我沒有爲每個請求設置LANGUAGE_CODE的中間件,所以django dms將它設置爲默認語言,因此將被「責備」爛攤子? –