2010-02-25 64 views
40

背景: 支付服務在幕後回撥支付結果時調用視圖 - 之後我需要以正確的語言發送電子郵件以確認支付等。我可以從支付服務器的請求中獲取語言代碼,並希望將其與Django的i18n系統一起使用,以確定使用哪種語言發送我的電子郵件。django視圖中的設置語言

因此,我需要設置我的django的語言從視圖內的應用程序。然後一次完成我的模板渲染和電子郵件。

設置request.session['django_language'] = lang只在測試時影響下一個視圖。

有沒有其他方法可以做到這一點?

乾杯,

蓋伊

回答

69

從Django的區域設置中間件(django.middleware.locale.LocaleMiddleware)引用部分:

from django.utils import translation 

class LocaleMiddleware(object): 
    """ 
    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). 
    """ 

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

translation.activate(language)是重要的一點。

+0

偉大的提示。幫助我解決了一個非常不相關的問題(文檔測試失敗了,因爲之前的一些測試使用了django的測試客戶端,導致系統出現意外的語言環境值。在doctest開始處停用deactivate_all()修復了這個問題) – 2011-06-10 11:27:51

+0

如何使用它,在我的自定義視圖中記錄用戶期間設置語言?語言代碼位於UserProfile表中。 – robos85 2011-06-21 19:38:13

+23

警告,由於translation.activate,我剛剛修復了當前開發中的一個錯誤:線程在請求​​之間重複使用並保持最後一種語言被激活。這導致了像Django管理切換語言一樣奇怪的東西。 如果您手動觸發transaction.activate,請不要忘記在渲染完所有字符串(這是LocaleMiddleware在渲染後執行的操作)後使用translation.deactivate。 – vincent 2012-03-21 09:08:18

2

request.LANGUAGE_CODE如果LocaleMiddleware激活

3

有時候你想強制執行給定的觀點有一定的語言,但讓瀏覽器語言設置爲首選的意見,其餘的語言。我還沒有想出如何改變視圖代碼的語言,但你可以通過一個簡單的中間件做到這一點

lang_based_on_url_middleware.py:

from django.utils import translation 

# Dictionary of urls that should use special language regardless of language set in browser 
# key = url 
# val = language code 
special_cases = { 
    '/this/is/some/url/' : 'dk', 
    '/his/is/another/special/case' : 'de', 
       } 

class LangBasedOnUrlMiddleware(object): 
    def process_request(self, request): 
     if request.path_info in special_cases: 
      lang = special_cases[request.path_info] 
      translation.activate(lang) 
      request.LANGUAGE_CODE = lang 

在settings.py:

MIDDLEWARE_CLASSES = (
    ... 
    'django.middleware.locale.LocaleMiddleware', 
    'inner.lang_based_on_url_middleware.LangBasedOnUrlMiddleware', # remember that the order of LocaleMiddleware and LangBasedOnUrlMiddleware matters 
    ... 
) 

不是一個優雅的解決方案,但它的工作原理。

10

一定還要在process_response中添加deactivate,否則你會遇到不同線程的問題。

from django.utils import translation 

class LocaleMiddleware(object): 
    """ 
    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). 
    """ 

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

    def process_response(self, request, response): 
     translation.deactivate() 
     return response 
+0

由於我在使用中間件時經歷了一個奇怪的行爲而沒有停用翻譯,我不知道爲什麼這會在線程中產生問題。無論如何,謝謝你的重要提示。 +1 – 2013-03-27 22:41:13

0

如果只是想獲得無論出於何種原因語言翻譯的字符串,可以use override as a decorator這樣的:

from django.utils import translation 
from django.utils.translation import ugettext as _ 

with translation.override(language): 
    welcome = _('welcome') 
0

如果您正在使用Django 1.10或更高版本,還有自定義一個新的語法中間件:

from django.utils import translation 

class LocaleMiddleware(object): 

    def __init__(self, get_response): 
     self.get_response = get_response 

    def __call__(self, request): 

     language_code = 'en' #TODO, your logic 

     translation.activate(language_code) 

     response = self.get_response(request) 

     translation.deactivate() 

     return response 
0

使用基於類的觀點,這應該工作:

class YourView(SomeBuiltInView): 
def get(self, request, *args, **kwargs): 
    setattr(request, 'LANGUAGE_CODE', 'YOUR_LANGUAGE_CODE') 
    return super().get(self, request, *args, **kwargs) 

基本上你所做的只是讓視圖渲染器認爲請求來自YOUR_LANGUAGE_CODE而不是原來的真實。