我什么时候应该使用ugettext_lazy?


141

我有一个关于使用ugettext和ugettext_lazy进行翻译的问题。我了解到,在模型ugettext_lazyugettext中,我应该在中使用。但是还有其他地方我也应该使用ugettext_lazy吗?表单定义呢?它们之间是否存在性能差异?

编辑: 还有一件事。有时候,代替ugettext_lazyugettext_noop被使用。正如文档所述,ugettext_noop仅在将字符串显示给用户之前,才将字符串标记为要翻译,并在可能的最新情况下进行翻译,但是我在这里有点困惑,这与功能相似ugettext_lazy吗?我仍然很难决定在模型和表格中应该使用哪个。

Answers:


196

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

15
在我看来,这比Django文档中的解释更容易理解。谢谢@伯恩哈德。
Utku

14
谢谢!解释什么时候使用ugettext_lazy 也很有帮助,例如何时将其传递给需要字符串如“” .replace,字符串连接等的东西。在这种情况下,惰性代理对象将无法工作。否则,此答案表明您始终使用ugettext_lazy是安全的。
mrooney

4
@mrooney这些情况的重要性较小,因为如果您这样做,它们会给您带来错误,而不是默默地返回错误的语言翻译。另外,您可以在ugettext_lazy中使用“ ..replace”,只需在结果上调用str(),例如lazytext = ugettext_lazy('hello'),然后再使用str(lazytext).replace。
fabspro 2014年

1
怎么样msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop ?如果没有_noop,Django会找不到字符串需要翻译?
WeizhongTu

1
翻译适用于变量。同样,这是一个相同的示例docs,为什么_noop呢?
WeizhongTu


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,而不是“ client”的字符串,它将具有一个代理对象。代理对象无法序列化为json。


2
在这种情况下,您应该使用ugettext。
sudip '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.