USE_I18N=True 必须开启以支持翻译,USE_L10N=False 更安全,避免本地化格式意外;LANGUAGE_CODE 应设为 'zh-hans'(BCP 47 格式);makemessages 需用 -l zh-hans;模板中优先用 {% translate %},变量插值必须用 {% blocktrans %};LOCALE_PATHS 应指向 locale 父目录;修改 .po 后务必运行 compilemessages。

settings.py 里 USE_I18N 和 USE_L10N 到底要不要都开?
只开 USE_I18N=True,USE_L10N=False 就够了。前者控制翻译(i18n),后者管本地化格式(l10n,比如日期、数字分隔符),两者独立。开了 USE_L10N 却没配 LANGUAGE_CODE 或中间件,反而容易让 date 模板过滤器输出意外格式。
实操建议:
-
USE_I18N = True必须设为True,否则gettext不生效,makemessages也扫不到字符串 -
USE_L10N = False更安全;真要本地化格式,优先用django.utils.formats显式处理,别依赖全局开关 -
LANGUAGE_CODE = 'zh-hans'要写对——不是zh_CN,Django 只认 BCP 47 格式(带连字符) - 时区相关配置
TZ和语言无关,别混进来
为什么 makemessages -l zh_Hans 报错说 “unknown language”?
Django 默认只认标准语言代码,zh_Hans 是错的写法,下划线不行,大小写也不对。它要的是 zh-hans(小写 + 连字符)。
常见错误现象:
立即学习“Python免费学习笔记(深入)”;
CommandError: Unknown language code "zh_Hans"-
makemessages成功运行但生成空.po文件(实际是语言代码不匹配,消息被丢弃)
实操建议:
- 查支持列表:
python manage.py makemessages --list,里面显示的就是合法值,如zh-hans、en-us、ja - 生成命令必须用连字符:
python manage.py makemessages -l zh-hans - 如果想加繁体中文,用
zh-hant,不是zh_TW(后者是 locale,Django i18n 层不直接认) - 自定义语言代码需在
LANGUAGES中显式声明,否则get_language_info等函数会失败
模板里 {% trans %} 和 {% translate %} 有啥区别?
{% trans %} 是老写法,{% translate %} 是 Django 3.1+ 推荐替代——但两者行为完全一致,只是语法糖。真正影响提取的是是否被 gettext 工具识别,而不是模板标签名。
使用场景和坑:
- 变量插值必须用
{% blocktrans %},{% trans %}只吃纯字符串,写{% trans "Hello {{ name }}" %}会直接报错 -
{% blocktrans %}里不能用过滤器,{{ value|lower }}无效,得先在视图里处理好再传进去 - 提取时
makemessages默认只扫.py、.html、.txt,如果用了.jinja或其他后缀,得加-e .jinja - 字符串带换行或单引号容易漏提:用三引号或转义,
_("Line1\nLine2")比_("Line1\ Line2")更稳
LOCALE_PATHS 配置错位置,翻译文件就白生成
LOCALE_PATHS 不是指向 locale/ 目录本身,而是指向包含 locale/ 的父目录。很多人把它设成 ['myapp/locale'],结果 makemessages 在项目根目录下建了个新 locale/,而 runserver 却去 myapp/locale 找——根本对不上。
实操建议:
- 推荐统一放项目根目录:
LOCALE_PATHS = [BASE_DIR / 'locale'](Django 3.1+ 支持pathlib),然后makemessages -l zh-hans会自动建locale/zh-hans/LC_MESSAGES/django.po - 如果分散在各 app,确保每个 app 下有
locale/子目录,并且LOCALE_PATHS为空(Django 默认扫描每个 INSTALLED_APPS 下的locale/) -
LocaleMiddleware启用后,请求语言才真正生效;光配LANGUAGE_CODE只是默认 fallback,用户看不到切换效果 -
django.po编辑完必须编译:python manage.py compilemessages,否则运行时还是英文——这个步骤最容易被跳过
最常被忽略的其实是 compilemessages 的执行时机:CI 流水线里没加这步,或者开发时改了 .po 但忘了重编译,页面就一直不翻。它不自动触发,也没热重载。


















