2010-02-25 7 views
40

background: Widok nazywa gdy pingi usług płatniczych poprzeć wyniku płatności za kulisami - afterwhich muszę wysłać e-mail w odpowiednim języku, aby potwierdzić płatność i tak dalej. Mogę odzyskać kod języka w żądaniu z serwera płatności i chciałbym go użyć wraz z systemami i18n Django, aby określić, w jakim języku mam wysyłać moje wiadomości.zestaw język w widoku django

Potrzebuję ustawić język mojego django aplikacja z widoku. A następnie wykonaj rendering mojego szablonu i wyślij e-mailem wszystko za jednym razem.

ustawienie request.session['django_language'] = lang wpływa tylko na następny widok podczas testowania.

Czy jest jakiś inny sposób na zrobienie tego?

Cheers,

Guy

Odpowiedz

69

Cytując części z Django Locale Middleware (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) jest ważny bit.

+0

Świetna wskazówka. Pomógł mi rozwiązać dość niezwiązany problem, który miałem (gdzie testowanie zawodziło, ponieważ niektóre wcześniejsze testy używały klienta testowego django, który zostawił system z nieoczekiwaną wartością ustawienia narodowego.) Dodawanie tłumaczenia.deactivate_all() na początku doctest naprawił problem) –

+0

Jak mogę go użyć, aby ustawić język podczas logowania użytkownika w moim widoku niestandardowym? Kod języka znajduje się w tabeli UserProfile. – robos85

+23

Ostrzeżenie, Właśnie naprawiłem błąd w bieżącym rozwoju, ze względu na translation.activate: wątki są ponownie wykorzystywane między żądaniami i utrzymują aktywację ostatniego języka. Prowadzi to do dziwnych rzeczy, takich jak zmiana języka przez cały czas. Jeśli ręcznie uruchomisz plik transaction.activate, nie zapomnij użyć polecenia translation.deactivate po wyrenderowaniu wszystkich napisów (to właśnie robi LocaleMiddleware po renderowaniu). – vincent

3

Czasami chcesz wymusić pewien język dla danego widoku, ale niech wybór ustawień językowych przeglądarka język reszty poglądami. Nie zorientowali się, jak zmienić język w kodzie widoku, ale można to zrobić poprzez wdrożenie prostego Middleware

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 

W settings.py:

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

Nie jest to eleganckie rozwiązanie, ale działa.

10

Pamiętaj również o dodaniu deaktywacji w process_response, w przeciwnym razie będziesz mieć problemy z różnymi wątkami.

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

Gdy doświadczyłem dziwnego zachowania przy użyciu oprogramowania pośredniego bez dezaktywacji tłumaczenia, zastanawiam się, dlaczego powoduje to problemy z wątkami. W każdym razie, dzięki za ważną wskazówkę. +1 –

0

Jeśli tylko chcesz dostać przetłumaczone ciągi dla języka, z jakiegokolwiek powodu, można use override as a decorator tak:

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

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

Jeśli używasz Django 1.10 lub nowszy, nowe składnia zwyczaju middleware:

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

Z widokiem na bazie klasy, to powinno działać:

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

Zasadniczo wszystko, co robisz, powoduje, że renderer widoku uważa, że ​​żądanie pochodziło z YOUR_LANGUAGE_CODE, a nie z pierwotnej prawdy.

Powiązane problemy