Django2.0国际化在服务器环境失效问题求助
问题描述
我遇到一个困扰已久的问题:本地环境下,不管是用python3 manage.py runserver还是uwsgi --http :8000 xxx.uwsgi启动服务,Django的国际化功能都能正常工作。但把代码部署到服务器后,国际化完全失效。
相关配置
LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')] # print(LOCALE_PATHS) LANGUAGE_CODE = 'en-us' LANGUAGES = [ ('en-us', t_l('English')), ('zh-hans', t_l('Chinese')) ] USE_TZ = True TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'util.middleware.MultipleDomainMiddleware', 'util.middleware.VisitHistoryMiddleware', 'django.middleware.gzip.GZipMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 'debug_toolbar.middleware.DebugToolbarMiddleware', ]
本地化文件路径
.mo和.po文件存放路径:/project/locale/zh_hans/LC_MESSAGES/xxx.po、/project/locale/zh_hans/LC_MESSAGES/xxx.mo
补充信息
- 网页模板顶部已添加
{% load i18n %},本地测试完全正常 - 服务器采用
nginx + uwsgi + Django部署,已确认服务器能获取正确的request.LANGUAGE_CODE - 服务器上直接运行
python3 manage.py runserver或uwsgi --http,国际化仍无法工作 - 服务器系统为Ubuntu 16.04,gettext版本为0.19.7-2ubuntu3(通过
apt-get安装)
解决方案
结合你的情况,本地正常但服务器全场景失效,大概率是本地化文件权限、路径、编译问题,或者服务器系统locale支持缺失,以下是逐步排查方向:
1. 检查本地化文件的权限与归属
服务器上的.mo/.po文件可能没有被Django进程读取的权限,或者文件归属用户与uwsgi运行用户不匹配(比如uwsgi用www-data运行,但文件归属是root)。
执行以下命令修复:
# 递归设置locale目录下所有文件为可读权限 chmod -R 644 /project/locale/ # 递归修改文件归属为uwsgi运行用户(假设是www-data) chown -R www-data:www-data /project/locale/
2. 确认LOCALE_PATHS的实际路径
你配置了LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')],但服务器上的BASE_DIR可能和本地不一致,导致Django找不到本地化目录。
在服务器上启动Django Shell验证:
python3 manage.py shell
执行代码查看实际路径:
import os from django.conf import settings print(settings.BASE_DIR) print(settings.LOCALE_PATHS)
如果输出的路径和实际的/project/locale不符,需要调整LOCALE_PATHS配置,或者将locale目录移到正确位置。
3. 重新编译本地化文件
可能服务器上的.mo文件编译不完整或出错,在服务器上重新执行编译命令:
python3 manage.py compilemessages
注意查看输出是否有错误提示(比如.po文件编码问题、语法错误),根据提示修复后重新编译。
4. 检查服务器系统的locale支持
Ubuntu 16.04默认可能没有安装中文locale,导致gettext无法正常切换语言。执行以下命令检查已安装的locale:
locale -a
如果输出中没有zh_CN.UTF-8或zh_HANS.UTF-8,需要安装中文locale:
sudo locale-gen zh_CN.UTF-8 sudo update-locale LANG=zh_CN.UTF-8
安装完成后重启uwsgi和nginx服务。
5. 检查uwsgi的环境变量配置
uwsgi运行时可能缺失LC_ALL或LANG环境变量,导致gettext无法正常工作。可以在uwsgi配置文件中添加:
env = LC_ALL=en_US.UTF-8 env = LANG=en_US.UTF-8
或者启动uwsgi时临时指定:
uwsgi --http :8000 xxx.uwsgi --env LC_ALL=en_US.UTF-8 --env LANG=en_US.UTF-8
修改后重启uwsgi测试。
6. 排查自定义中间件的干扰
你的Middleware中LocaleMiddleware的位置是正确的(在SessionMiddleware之后、CommonMiddleware之前),但自定义的MultipleDomainMiddleware或VisitHistoryMiddleware可能干扰了语言设置。可以暂时注释这两个中间件,测试国际化是否恢复正常,排查是否存在冲突。
内容的提问来源于stack exchange,提问作者jhd

