Коли я повинен використовувати ugettext_lazy?


141

У мене питання щодо використання ugettext та ugettext_lazyдля перекладів. Я дізнався, що в моделях я повинен використовуватись ugettext_lazy, тоді як у переглядах ugettext. Але чи є ще якісь місця, де я ugettext_lazyтеж повинен використовуватись ? Що щодо визначення форм? Чи є різниці між продуктивністю між ними?

Редагувати: І ще одне. Іноді, замість того ugettext_lazy, ugettext_noopвикористовується. Як йдеться в документації, ugettext_noopрядки позначаються лише для перекладу та перекладені в останній можливий момент перед тим, як показати їх користувачеві, але я тут трохи плутаюсь, чи не схоже на те, що ugettext_lazyробити? Мені все ще важко вирішити, що мені слід використовувати в своїх моделях та формах.

Відповіді:


197

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
Це зрозуміліше, ніж пояснення в документації Джанго на мій погляд. Дякую @Bernhard.
Утку

14
Дякую! Було б також корисно пояснити, коли не використовувати ugettext_lazy, наприклад, при передачі його речам, які очікують рядок типу "" .seplace, string concatenation та інші; лінивий об'єкт проксі не працюватиме в цих випадках. В іншому випадку ця відповідь означає, що ви безпечні, завжди використовуючи ugettext_lazy.
mrooney

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

1
що з msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop, ?якщо без цього _noop, django не знайде рядок, необхідний для перекладу?
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.