Django项目混用ugettext与ugettext_lazy时字符串收集异常问题
嗨,我之前做Django项目翻译时也踩过类似的坑,结合你的情况,给你几个针对性的排查和解决方向:
指定makemessages的扫描关键词
默认情况下,makemessages只会识别_()、gettext()这类常见的翻译函数别名。如果你直接使用ugettext()或ugettext_lazy()而不是_(),必须通过--keyword参数告诉命令去扫描这些函数。执行命令时加上对应的关键词:python manage.py makemessages -l zh_Hans --keyword=ugettext --keyword=ugettext_lazy要是有其他自定义的翻译函数,也可以用多个
--keyword参数添加进去。确认字符串是静态可扫描的
Django的makemessages是静态分析代码的,所以如果你的翻译字符串是在运行时动态生成的(比如放在函数内部的变量里,或者通过动态逻辑返回),它会扫描不到。比如:# 错误示例:静态扫描无法识别变量中的字符串 def some_func(): msg = "用户昵称" return ugettext(msg) # 正确示例:直接把字符串传入翻译函数 def some_func(): return ugettext("用户昵称")模型中如果是在动态方法里返回翻译字符串,也要确保字符串直接写在
ugettext参数里,而不是先赋值给变量再传递。检查LOCALE_PATHS配置
确保你的settings.py里配置了正确的LOCALE_PATHS,并且对应的目录结构存在且有权限写入:LOCALE_PATHS = [ os.path.join(BASE_DIR, 'locale'), ]对应的目录应该是
locale/[语言代码]/LC_MESSAGES/,比如locale/zh_Hans/LC_MESSAGES/,如果目录不存在,手动创建后再运行makemessages。验证模型中ugettext_lazy的使用场景
模型字段的verbose_name、help_text这类需要在加载时就翻译的属性,必须用ugettext_lazy,但要确保是直接赋值:# 正确写法 class UserProfile(models.Model): bio = models.TextField(verbose_name=ugettext_lazy("个人简介")) # 不推荐写法(静态扫描可能漏过) class UserProfile(models.Model): def get_bio_verbose(self): return ugettext_lazy("个人简介") bio = models.TextField(verbose_name=get_bio_verbose())重新运行makemessages并检查po文件
做完以上调整后,先删除旧的po文件,再重新运行makemessages命令,然后打开生成的.po文件,搜索你要翻译的字符串,确认是否已经被收集到。
内容的提问来源于stack exchange,提问作者MoaMoaK

