第二十三章 翻译与国际化

篇别:第三篇 数据库与数据管理

本章学习目标

  • 能在 Python/XML 中正确使用 _()导出/导入 .po
  • 理解 可翻译字段translate=True)在 数据库中的存储(含 JSONB 演进)。
  • 能通过 context 切换语言 读取与生成 多语言内容
  • 能规划 网站、报表、邮件 的多语言策略。

导读:国际化不是「事后翻译」

从第一天起:用户可见字符串可提取动态用户内容 不应包进 _()。字段 translate=True 使 同一记录 在不同 lang 下显示不同 name/description,存储形态随版本演进。


23.1 _() 函数

23.1.1 知识要点

from odoo import _
  • 静态英文(或源语言) 作为 msgid.po 提供各语言 msgstr
  • 格式化_('最多 %s 天') % nPython 3.14 前 注意 % 与 gettext 的交互;亦可用 .format(注意翻译语序)。
  • 勿翻译:用户昵称、SKU、日志中的原始 JSON。

23.1.2 案例

raise UserError(_('借阅天数不能超过 %s 天') % max_days)
selection = [
    ('draft', _('草稿')),
    ('done', _('完成')),
]

23.1.3 截图占位

图 23-1 导出翻译

23.1.4 本节练习

  1. 改错_(partner.name) 是否合理?
  2. 实操:新增一条 中文 界面可见字符串,导出 zh_CN.po 并填译。
  3. 简答f-string_() 组合时的常见陷阱?

参考答案提示:1. 不合理,name 是数据不是 UI 源文。3. 翻译无法提取静态句柄。


23.2 .po 文件

23.2.1 知识要点

  • 路径i18n/zh_CN.poi18n/de.po 等。
  • 条目msgid / msgstrfuzzy 标记。
  • 合并:升级后 msgmerge 或 Odoo 重新导出。

23.2.3 截图占位

图 23-2 Poedit

23.2.4 本节练习

  1. 实操:用 Poedit 打开 zh_CN.po,保存并 导入 到数据库。
  2. 简答fuzzy 条目的含义?

23.3 翻译导入导出与 CI

23.3.1 知识要点

  • CLI / 界面:加载翻译、覆盖模式。
  • CI:检测 未翻译msgstr "")、过时 fuzzy

23.3.2 本节练习

  1. 简答:如何在 GitHub Actions 中跑一条 gettext 检查(思路即可)?

23.4 JSONB 翻译存储(新增)

23.4.1 知识要点

自较新版本起,部分 translate=True 字段在 PostgreSQL 中以 JSONB 存多语言 键值en_USzh_CN 等)。

SQL 报表->> 取指定语言或 回退逻辑

23.4.3 截图占位

图 23-3 列类型 jsonb

23.4.4 本节练习

  1. 简答:ORM read 返回的 可翻译 Char 与 DB 原始列差异?
  2. 实操psqlSELECT name FROM ... LIMIT 1 观察 JSON 形态(测试库)。

23.5 Environment 翻译 API(新增)

23.5.1 知识要点

使用 with_context(lang='xx_XX') 切换:

for lang in ['en_US', 'zh_CN']:
    name = book.with_context(lang=lang).name

env._ 等环境级翻译(以 19.0 文档为准)。

23.5.3 截图占位

图 23-4 官方 i18n 文档

23.5.4 本节练习

  1. 实操:同一图书在 中英文name 字段 显示不同(需 translate=True 与两条翻译)。
  2. 简答报表 PDF 固定为 公司账套语言 的实现思路?

本章综合练习

  1. 方案报表 PDF 语言 = 用户偏好 vs 公司默认,列表 利弊
  2. SEO:网站 hreflang 与 Odoo 多网站/多语言 关系(拓展阅读笔记)。
  3. 质量:建立团队 「禁止硬编码中文在 Python」 的 review 规则一条。
  4. 数据库:写出 SQL 从 JSONB namezh_CN 的伪代码。

本章对应白皮书目录:第二十三章 翻译与国际化。