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

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

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

Ответ 1

ugettext() vs. ugettext_lazy()

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

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

Относительно ugettext_noop()

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

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

Ответ 2

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

Ответ 3

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

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.