Kiedy należy używać ugettext_lazy?

141

Mam pytanie dotyczące używania ugettext i ugettext_lazytłumaczeń. Dowiedziałem się, że w modelach powinienem używać ugettext_lazy, podczas gdy w widokach ugettext. Ale czy są jakieś inne miejsca, z których ja też powinienem skorzystać ugettext_lazy? A co z definicjami formularzy? Czy są między nimi różnice w wydajności?

Edycja: I jeszcze jedna rzecz. Czasami, zamiast ugettext_lazy, ugettext_noopjest używany. Jak mówi dokumentacja, ugettext_noopciągi znaków są zaznaczane tylko do tłumaczenia i tłumaczone najpóźniej przed wyświetleniem ich użytkownikowi, ale jestem trochę zdezorientowany, czy nie jest to podobne do tego ugettext_lazy, co zrobić? Nadal ciężko mi zdecydować, które powinienem zastosować w moich modelach i formach.

Dzejkob
źródło

Odpowiedzi:

197

ugettext() vs. ugettext_lazy()

W definicjach takich jak formularze lub modele powinieneś używać, ugettext_lazyponieważ kod tych definicji jest wykonywany tylko raz (głównie przy starcie django); ugettext_lazyleniwie tłumaczy struny, czyli np. za każdym razem, gdy uzyskasz dostęp do nazwy atrybutu w modelu, łańcuch zostanie przetłumaczony na nowo - co ma sens, ponieważ możesz patrzeć na ten model w różnych językach od czasu uruchomienia django!

W widokach i podobnych wywołaniach funkcji możesz używać ugettextbez problemów, ponieważ za każdym razem, gdy wywoływany jest widok, ugettextbędzie on wykonywany na nowo, więc zawsze otrzymasz odpowiednie tłumaczenie pasujące do żądania!

Jeżeli chodzi o ugettext_noop()

Jak zauważył Bryce w swojej odpowiedzi, funkcja ta oznacza ciąg jako możliwy do wyodrębnienia do tłumaczenia, ale zwraca nieprzetłumaczony ciąg. Jest to przydatne do używania łańcucha w dwóch miejscach - przetłumaczone i nieprzetłumaczone. Zobacz poniższy przykład:

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
źródło
16
Moim zdaniem jest to bardziej zrozumiałe niż wyjaśnienie w dokumentacji Django. Dzięki @Bernhard.
Utku
14
Dzięki! Byłoby również pomocne wyjaśnienie, kiedy nie należy używać ugettext_lazy, na przykład podczas przekazywania go do rzeczy, które oczekują łańcucha, takiego jak "" .replace, konkatenacja ciągów i inne; leniwy obiekt proxy nie będzie działał w takich przypadkach. W przeciwnym razie ta odpowiedź oznacza, że ​​jesteś bezpieczny, używając tylko ugettext_lazy.
mrooney
4
@mrooney te sprawy mają mniejsze znaczenie, ponieważ jeśli to zrobisz, dadzą ci błąd, zamiast po cichu zwracać niewłaściwe tłumaczenie na język. Możesz także użyć "" .replace z ugettext_lazy, wystarczy wywołać str () na wyniku, np. Lazytext = ugettext_lazy ('hello'), a następnie użyć str (lazytext) .replace.
fabspro
1
a co z msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop, ?jeśli bez _noop, django nie znajdzie napisu wymagającego tłumaczenia?
WeizhongTu
1
Tłumaczenie działa na zmiennych. Ponownie, oto identyczne przykładowe dokumenty , więc dlaczego _noop?
WeizhongTu,
17

Znakomitym zastosowaniem _noop jest, gdy chcesz zarejestrować wiadomość w języku angielskim dla programistów, ale zaprezentować przetłumaczony ciąg widzowi. Przykład tego znajduje się pod adresem http://blog.bessas.me/posts/using-gettext-in-django/

Bryce
źródło
4
Link jest uszkodzony…
nalzok
5

Wersja leniwa zwraca obiekt proxy zamiast ciągu znaków iw niektórych sytuacjach nie będzie działać zgodnie z oczekiwaniami. Na przykład:

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')

nie powiedzie się, ponieważ ostatnia linia będzie próbowała serializować obiekt lst do formatu JSON i zamiast ciągu znaków dla „klienta” miałby obiekt proxy. Obiekt proxy nie jest możliwy do serializacji do json.

Alex Protyagov
źródło
2
W takich przypadkach powinieneś użyć ugettext.
sudip