Quando devo usar o ugettext_lazy?

141

Eu tenho uma pergunta sobre o uso do ugettext e ugettext_lazypara traduções. Aprendi que em modelos eu deveria usar ugettext_lazy, enquanto em visualizações ugettext. Mas existem outros lugares onde eu devo usar ugettext_lazytambém? E as definições de formulário? Existem diferenças de desempenho entre eles?

Edit: E mais uma coisa. Às vezes, em vez de ugettext_lazy, ugettext_noopé usado. Como a documentação diz, as ugettext_noopstrings são marcadas apenas para tradução e traduzidas no mais recente momento possível, antes de mostrá-las ao usuário, mas estou um pouco confuso aqui, não é semelhante ao que ugettext_lazyfaz? Ainda é difícil para mim decidir o que devo usar nos meus modelos e formulários.

Dzejkob
fonte

Respostas:

196

ugettext() vs. ugettext_lazy()

Em definições como formulários ou modelos, você deve usar ugettext_lazyporque o código dessas definições é executado apenas uma vez (principalmente na inicialização do django); ugettext_lazytraduz as cordas de uma maneira preguiçosa, o que significa, por exemplo. toda vez que você acessar o nome de um atributo em um modelo, a string será traduzida novamente - o que faz totalmente sentido, porque você pode estar olhando para esse modelo em diferentes idiomas desde que o django foi iniciado!

Em ugettextmodos de exibição e chamadas de função similares, você pode usar sem problemas, porque toda vez que o modo de exibição é chamado ugettextserá executado recentemente, para que você sempre obtenha a tradução correta conforme a solicitação!

A respeito de ugettext_noop()

Como Bryce apontou em sua resposta, essa função marca uma string como extraível para tradução, mas retorna a string não traduzida. Isso é útil para usar a string em dois lugares - traduzidos e não traduzidos. Veja o seguinte exemplo:

import logging
from django.http import HttpResponse
from django.utils.translation import ugettext as _, ugettext_noop as _noop

def view(request):
    msg = _noop("An error has occurred")
    logging.error(msg)
    return HttpResponse(_(msg))
Bernhard Vallant
fonte
15
Isso é mais compreensível do que a explicação na documentação do Django na minha opinião. Obrigado @Bernhard.
Utku
14
Obrigado! Também seria útil explicar quando não usar o ugettext_lazy, como transmiti-lo a coisas que esperam uma string como "" .place, concatenation de string e outros; um objeto proxy lento não funcionará nesses casos. Caso contrário, esta resposta implica que você está seguro, sempre usando o ugettext_lazy.
Mroney
4
@mrooney esses casos são menos importantes, pois você cometerá um erro se você os fizer, em vez de retornar silenciosamente a tradução errada do idioma. Além disso, você pode usar "" .replace com ugettext_lazy, basta chamar str () no resultado, por exemplo, lazytext = ugettext_lazy ('olá') e depois usar str (lazytext) .replace.
Fabspro #
1
que tal msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop ?se sem _noop, o django não encontrou a string que precisa ser traduzida?
WeizhongTu
1
A tradução funciona em variáveis. Novamente, aqui está um exemplo de documentação idêntica , então por que _noop?
WeizhongTu
17

Um excelente uso de _noop é quando você deseja registrar uma mensagem em inglês para os desenvolvedores, mas apresenta a string traduzida para um visualizador. Um exemplo disso está em http://blog.bessas.me/posts/using-gettext-in-django/

Bryce
fonte
4
O link está quebrado…
nalzok 29/03
5

A versão lenta retorna um objeto proxy em vez de uma string e, em algumas situações, não funcionaria conforme o esperado. Por exemplo:

def get(self, request, format=None):
   search_str = request.GET.get('search', '')
   data = self.search(search_str)
   lst = []
   lst.append({'name': ugettext_lazy('Client'), 'result': data})
   return HttpResponse(json.dumps(lst), content_type='application/json')

falharia porque a última linha tentaria serializar o objeto lst em JSON e, em vez de uma string para "client", teria um objeto proxy. O objeto proxy não pode ser serializado no json.

Alex Protyagov
fonte
2
Você deve usar o ugettext nesses casos.
sudip 11/05