web-dev-qa-db-fra.com

définir la langue dans une vue Django

Arrière-plan: La vue est appelée lorsqu'un service de paiement renvoie un résultat de paiement en coulisse, après quoi je dois envoyer un e-mail dans la bonne langue pour confirmer le paiement, etc. Je peux récupérer le code de langue dans la demande du serveur de paiement et souhaiterais l’utiliser avec les systèmes i18n de Django pour déterminer la langue dans laquelle envoyer mon courrier électronique.

Je dois donc définir la langue de mon application Django dans une vue. Et puis faire mon modèle de rendu et emailing en une seule fois.

la définition de request.session['Django_language'] = lang n'affecte que la vue suivante lorsque je teste.

Y a-t-il un autre moyen de le faire?

À votre santé,

Gars

49
Guy Bowden

Pour citer des parties de Locale Middleware de 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) est le bit important.

78
stefanw

Assurez-vous également d'ajouter deactivate dans process_response, sinon vous aurez des problèmes avec différents threads.

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
12
webjunkie

Parfois, vous souhaitez appliquer une langue donnée à une vue donnée tout en laissant les paramètres de langue du navigateur choisir la langue pour les autres vues. Je n'ai pas trouvé comment changer la langue dans le code d'affichage, mais vous pouvez le faire en implémentant un simple 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

Dans settings.py:

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

Pas une solution élégante mais ça marche.

3
Helgi Borg

Vous pouvez envisager de stocker la langue dans le modèle utilisateur et utiliser ce middleware personnalisé Django-user-language-middleware .

Cela facilite la traduction de votre application Django en regardant la langue sélectionnée dans le champ user.language et vous pouvez toujours connaître les préférences linguistiques de n'importe quel utilisateur.

Usage:

  1. Ajoutez un champ de langue à votre modèle d'utilisateur:

    class User(auth_base.AbstractBaseUser, auth.PermissionsMixin):
        # ...
        language = models.CharField(max_length=10,
                                    choices=settings.LANGUAGES,
                                    default=settings.LANGUAGE_CODE)
    
  2. Installez le middleware à partir de pip:

    pip install Django-user-language-middleware

  3. Ajoutez-le à la liste des classes de votre middleware dans les paramètres pour écouter les demandes:

    MIDDLEWARE = [  # Or MIDDLEWARE_CLASSES on Django < 1.10
        ...
        'user_language_middleware.UserLanguageMiddleware',
        ...
    ]
    

J'espère que cela aidera les gens à se poser sur cette question à l'avenir.

2
Laura Barluzzi

Si vous voulez juste obtenir les chaînes traduites pour une langue pour quelque raison que ce soit, vous pouvez utiliser override en tant que décorateur comme ceci:

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

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

request.LANGUAGE_CODE si LocaleMiddleware activé

2
DenisKolodin

Si vous utilisez Django 1.10 ou supérieur, il existe une nouvelle syntaxe pour le middleware personnalisé:

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
1
Patrik Beck

Avec les vues basées sur les classes, cela devrait fonctionner:

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

En gros, tout ce que vous faites est de faire en sorte que le rendu de vue pense que la requête provient de YOUR_LANGUAGE_CODE plutôt que de ce qui était à l'origine vrai.

0
emihir0