2010-02-25 14 views
40

sfondo: La vista è chiamata quando un ping di servizi di pagamento indietro un esito pagamento dietro le quinte - dopodiché ho bisogno di inviare una e-mail nella lingua giusta per confermare il pagamento e così via. Posso recuperare il codice della lingua nella richiesta dal server di pagamento e vorrei utilizzarlo insieme ai sistemi i18n di Django per determinare in quale lingua inviare le mie email.lingua impostata all'interno di una vista Django

Quindi ho bisogno di impostare la lingua del mio django app dall'interno di una vista. E poi esegui il rendering del modello e l'invio via email tutto in una volta.

l'impostazione request.session['django_language'] = lang ha effetto solo sulla vista successiva quando eseguo il test.

C'è un altro modo per farlo?

Cheers,

Guy

risposta

69

di citare parti dal di 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() 

Il translation.activate(language) è il bit importante.

+0

Ottimo suggerimento. Mi ha aiutato a risolvere un problema abbastanza estraneo che avevo (in cui un doctest stava fallendo perché alcuni test precedenti usavano il client di prova di django, che lasciava il sistema con un valore inaspettato di locale.deactivate_all() all'inizio del doctest risolve il problema) –

+0

Come posso usarlo, per impostare la lingua durante la registrazione dell'utente nella mia visualizzazione personalizzata? Il codice della lingua è posto nella tabella UserProfile. – robos85

+23

Attenzione, ho corretto un bug in uno sviluppo attuale, dovuto a translation.activate: i thread sono riutilizzati tra le richieste e mantiene l'ultima lingua attivata. Questo ha portato a cose strane come l'amministrazione di django che cambia lingua tutto il tempo. Se si attiva manualmente transaction.activate, non dimenticare di utilizzare translation.deactivate dopo che tutte le stringhe sono state renderizzate (questo è ciò che LocaleMiddleware fa dopo il rendering). – vincent

2

request.LANGUAGE_CODE se LocaleMiddleware attivato

3

A volte si desidera imporre una determinata lingua per una determinata vista, ma lasciare che la scelta impostazioni della lingua del browser la lingua per il resto dei punti di vista. Non ho capito come cambiare la lingua nel codice della vista, ma si può fare questo grazie all'implementazione di un semplice 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 

In settings.py:

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

Non è una soluzione elegante ma funziona.

10

Assicurarsi di aggiungere anche disattivare in process_response, altrimenti si avranno problemi con thread diversi.

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

Come ho sperimentato uno strano comportamento utilizzando il middleware senza disattivare la traduzione, mi chiedo perché questo crea problemi con i thread. Comunque, grazie per l'importante suggerimento. +1 –

0

Se vogliono solo per ottenere le stringhe tradotte per un linguaggio per qualsiasi motivo, è possibile use override as a decorator in questo modo:

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

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

Se si utilizza Django 1.10 o superiore, c'è una nuova sintassi per la personalizzazione 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

Con vista sulla base di classe, questo dovrebbe funzionare:

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

Fondamentalmente tutto ciò che si fa è fare in modo che il renderizzatore della vista pensi che la richiesta provenga da YOUR_LANGUAGE_CODE piuttosto che in origine.

Problemi correlati