Django需手动启用gettext翻译:设USE_I18N=True,添加LocaleMiddleware,用makemessages提取、compilemessages编译.po文件,注意路径、命名(zh_Hans)、命令参数及DEBUG模式下热加载。

怎么在 Django 里开启 gettext 翻译支持
必须手动启用,Django 默认不自动加载翻译机制。光写 _("Hello") 没用,会原样输出字符串,连警告都不报。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 确保
USE_I18N = True和USE_L10N = True在settings.py中为True(后者非必需,但常配套用) - 把
'django.middleware.locale.LocaleMiddleware'加入MIDDLEWARE,位置要在SessionMiddleware之后、CommonMiddleware之前 -
INSTALLED_APPS里确认有'django.contrib.admin'(它自带翻译文件),否则部分内置提示不会本地化 - 语言选择依赖请求头
Accept-Language或 URL 前缀(如/en/),没配LocaleMiddleware就永远 fallback 到LANGUAGE_CODE
提取翻译字符串时为什么 makemessages 找不到 _()
常见错误是只扫描了 Python 文件,漏掉模板、JS 或自定义路径;或者用了不被识别的函数别名。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 运行
python manage.py makemessages -l zh_Hans前,先确认所有待翻译字符串都用了标准函数:只认_()、gettext()、ngettext()等,__()或t()不生效 - 模板中必须用
{% load i18n %}+{% trans "xxx" %}或{% blocktrans %}...{% endblocktrans %},直接写_()无效 - 若模板在
templates/外(比如 app 内templates/myapp/),加参数--locale zh_Hans --ignore=venv/* --extension html,txt,py显式指定 - JS 文件需额外加
--add-location=file和--no-wrap,且 JS 中必须用gettext("xxx"),不能用箭头函数包裹
LocaleMiddleware 怎么根据 URL 或域名切换语言
默认只看浏览器请求头,生产环境几乎不可用——用户换设备或清缓存就回退到英文,体验断裂。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 启用 URL 前缀模式:在主
urls.py用path('i18n/', include('django.conf.urls.i18n')),再把其他 URL 包进i18n_patterns();这样/en/about/和/zh-hans/about/自动生效 - 域名方案(如
zh.example.com)需自定义中间件,重写get_language_from_request(),从request.get_host()提取子域,再调用django.utils.translation.activate() - 切勿在视图里用
activate("zh-hans")后直接 render——它只影响当前线程,下个请求仍按中间件逻辑走;真要强制,得配合 session 或 cookie 存语言偏好 -
LANGUAGES设置必须包含实际支持的语言代码,比如[('en', 'English'), ('zh-hans', 'Simplified Chinese')],注意格式要和LOCALE_PATHS下目录名一致(zh_Hans≠zh-hans)
翻译文件编译后还是显示原文?常见卡点在哪
不是没生成 .mo,而是路径、命名或加载时机错了。最典型的是开发时改了 .po 却忘了 compilemessages。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 检查
LOCALE_PATHS是否指向正确目录(如[BASE_DIR / 'locale']),且该目录下结构为locale/zh_Hans/LC_MESSAGES/django.po—— 注意下划线不是短横,LC_MESSAGES必须全大写 - 运行
python manage.py compilemessages -l zh_Hans,不是zh-hans;失败时看终端是否报msgfmt: command not found(Linux/macOS 需装gettext包,Windows 用户得下gettext-bin并加进 PATH) - 模板里
{% get_current_language as LANGUAGE_CODE %}能查当前激活语言,但仅限已通过中间件或activate()设定过的值;如果始终是en,说明中间件根本没生效 - DEBUG=False 时,Django 不会自动重载翻译文件,改了
.po必须重启服务;开发期建议保持DEBUG=True并用runserver
语言包加载是静态的,compilemessages 后的 .mo 文件一旦生成,除非手动删或重编,否则不会响应 .po 的后续修改。路径拼错、大小写混用、命令漏参数——这三个地方占了八成问题。


















