Django中的"gettext()"与"gettext_lazy()

174 投票
4 回答
60377 浏览
提问于 2025-04-16 06:57

我有个关于使用 ugettext 和 gettext_lazy() 进行翻译的问题。 我了解到在模型中应该使用 gettext_lazy(),而在视图中使用 ugettext。 但是还有其他地方也应该使用 gettext_lazy() 吗?比如表单定义呢? 它们之间在性能上有什么区别吗?

编辑: 还有一件事。有时候,gettext_lazy() 被替换成 gettext_noop()。文档上说,gettext_noop() 的字符串只是标记为翻译,直到最后一刻才会翻译成用户能看到的内容,但我对此有点困惑,这不和 gettext_lazy() 的作用类似吗?我还是很难决定在我的模型和表单中应该使用哪个。

4 个回答

9

懒惰版本返回的是一个代理对象,而不是一个字符串,在某些情况下可能会出现意想不到的问题。例如:

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的。

23

一个很好的使用 _noop 的场景是,当你想给开发者记录一条英文信息,但又希望给用户显示翻译后的内容。举个例子,你可以参考这个链接:http://blog.bessas.me/posts/using-gettext-in-django/

247

gettext()gettext_lazy() 的区别

在定义表单或模型的时候,你应该使用 gettext_lazy。这是因为这些定义的代码只会执行一次(通常是在 Django 启动的时候)。gettext_lazy 是懒惰翻译字符串的,这意味着每次你访问模型的某个属性名称时,这个字符串都会被重新翻译。这是很有道理的,因为你可能在 Django 启动后会用不同的语言查看这个模型!

而在视图和类似的函数调用中,你可以放心使用 gettext,因为每次调用视图时,gettext 都会被重新执行,所以你总是能得到适合当前请求的正确翻译!

关于 gettext_noop()

正如 Bryce 在他的回答中提到的,这个函数的作用是标记一个字符串可以被提取用于翻译,但它返回的仍然是未翻译的字符串。这在需要在两个地方使用这个字符串时很有用——一个是翻译后的,另一个是未翻译的。下面是一个例子:

import logging
from django.http import HttpResponse
from django.utils.translation import gettext as _, gettext_noop as _noop

def view(request):
    msg = _noop("An error has occurred")
    logging.error(msg)
    return HttpResponse(_(msg))

撰写回答