Когда мне следует использовать ugettext_lazy?


145

У меня вопрос по использованию ugettext и ugettext_lazyдля переводов. Я узнал, что в моделях я должен использовать ugettext_lazy, а в представлениях - ugettext. Но есть ли другие места, где мне ugettext_lazyтоже стоит воспользоваться ? А как насчет определений форм? Есть ли различия в производительности между ними?

Изменить: И еще кое-что. Иногда вместо ugettext_lazy, ugettext_noopиспользуется. Как говорится в документации, ugettext_noopстроки помечаются только для перевода и переводятся в самое позднее время, прежде чем отобразить их пользователю, но я здесь немного запутался, разве это не похоже на то, что ugettext_lazyделают? Мне все еще сложно решить, что использовать в своих моделях и формах.

Ответы:


203

ugettext() vs. ugettext_lazy()

В определениях, таких как формы или модели, вы должны использовать, ugettext_lazyпотому что код этих определений выполняется только один раз (в основном при запуске django); ugettext_lazyпереводит строки лениво, что означает, например, каждый раз, когда вы обращаетесь к имени атрибута в модели, строка будет заново переведена - что совершенно логично, потому что вы могли смотреть на эту модель на разных языках с момента запуска django!

В представлениях и подобных вызовах функций вы можете использовать ugettextбез проблем, потому что каждый раз, когда вызывается представление, оно ugettextбудет выполняться заново, поэтому вы всегда получите правильный перевод, соответствующий запросу!

Что касается ugettext_noop()

Как указал Брайс в своем ответе, эта функция отмечает строку как извлекаемую для перевода, но возвращает непереведенную строку. Это полезно для использования строки в двух местах - переведенной и непереведенной. См. Следующий пример:

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

16
На мой взгляд, это более понятно, чем объяснение в документации Django. Спасибо @Bernhard.
Utku 02

14
Благодарность! Также было бы полезно объяснить, когда не следует использовать ugettext_lazy, например, при передаче его вещам, которые ожидают строку типа "" .replace, конкатенацию строк и другие; ленивый прокси-объект не будет работать в этих случаях. В противном случае этот ответ означает, что вы в безопасности, просто всегда используя ugettext_lazy.
mrooney

4
@mrooney эти случаи имеют меньшее значение, потому что они выдадут вам ошибку, если вы сделаете их, вместо того, чтобы молча вернуть неправильный языковой перевод. Кроме того, вы можете использовать "" .replace с ugettext_lazy, вам просто нужно вызвать str () для результата, например lazytext = ugettext_lazy ('hello'), а затем использовать str (lazytext) .replace.
fabspro 01

1
как насчет msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop, ?если без него _noopdjango не найдет строку, нуждающуюся в переводе?
WeizhongTu

1
Перевод работает с переменными. Опять же, вот идентичный пример документации , так почему _noop?
WeizhongTu

17

Отличное использование _noop - это когда вы хотите записать сообщение на английском языке для разработчиков, но представить переведенную строку зрителю. Пример этого находится на http://blog.bessas.me/posts/using-gettext-in-django/


4
Ссылка не работает…
nalzok

5

Ленивая версия возвращает прокси-объект вместо строки, и в некоторых ситуациях он не будет работать должным образом. Например:

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

потерпит неудачу, потому что самая последняя строка попытается сериализовать объект lst в JSON, и вместо строки для «клиента» у него будет прокси-объект. Прокси-объект не сериализуем в json.


2
В этих случаях вам следует использовать ugettext.
Sudip
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.