Django i18n本地正常但CI/CD部署后失效且出现CSRF错误
问题背景
本地运行的Django项目国际化翻译功能正常,但通过CI/CD流水线部署后出现以下问题:
- 翻译功能大面积失效,仅某一视图中的单个随机单词成功翻译
- 出现CSRF验证错误,尽管模板中已添加CSRF标签,视图也使用了
render方法
相关代码如下:
views.py
from django.shortcuts import render def test_page(request): return render(request, "translatetest.html")
应用级urls.py
from . import views from django.urls import path urlpatterns = [ path('test_page/', views.test_page, name='test_page'), ]
项目级urls.py
from django.contrib import admin from django.urls import include, path from django.conf.urls.i18n import i18n_patterns urlpatterns = [ path("admin/", admin.site.urls), path("i18n/", include("django.conf.urls.i18n")), ] urlpatterns += i18n_patterns ( path("", include("help_pages.urls"), name="help_pages"), # test_page 在此路由下 )
settings.py(国际化相关配置)
LANGUAGE_CODE = "en-us" TIME_ZONE = "UTC" USE_I18N = True USE_L10N = True USE_TZ = True LANGUAGES = [ ('en', ('English')), ('fr', ('French')), ] LOCALE_PATHS = ( os.path.join(BASE_DIR, 'locale'), )
排查与解决方案
一、翻译功能失效问题
确保CI/CD执行
compilemessages命令
Django的.po翻译源文件需要编译为.mo二进制文件才能被识别,本地可能手动执行过python manage.py compilemessages,但部署流水线大概率遗漏了这一步。需要在部署脚本中添加该命令,确保编译后的.mo文件被同步到服务器。验证LOCALE_PATHS路径与文件权限
在服务器上通过Django Shell执行from django.conf import settings; print(settings.LOCALE_PATHS),确认路径指向的locale目录存在,且包含对应语言的LC_MESSAGES子目录及完整的.po、.mo文件。同时检查web服务器用户(如www-data)对该目录及文件有读取权限。检查部署环境的语言配置一致性
确认服务器上的settings.py中LANGUAGE_CODE、LANGUAGES、USE_I18N等配置与本地完全一致,避免CI/CD过程中被环境变量或配置文件覆盖。排查翻译文件同步完整性
确认CI/CD流水线完整同步了本地的locale目录,没有遗漏翻译文件。个别单词翻译成功可能是因为该词汇属于Django内置翻译(如Admin模块),其.mo文件由Django自身提供,不受项目翻译文件影响。
二、CSRF验证错误问题
修正模板中的CSRF标签格式
检查模板中的CSRF标签是否为正确格式{% csrf_token %},注意是下划线连接而非空格(你提到的{% csrf token %}存在格式错误,这会导致标签不生效)。添加CSRF_TRUSTED_ORIGINS配置
如果项目部署在反向代理(如Nginx)或特定域名下,需要在settings.py中添加信任的来源:CSRF_TRUSTED_ORIGINS = ['https://your-production-domain.com'] # 替换为实际域名否则Django会认为请求来源不可信,拒绝CSRF验证。
检查Cookie配置
若使用子域名或反向代理,需确认SESSION_COOKIE_DOMAIN、CSRF_COOKIE_DOMAIN配置正确,确保前端能正常获取到CSRF Cookie。例如:CSRF_COOKIE_DOMAIN = ".your-domain.com" # 适配子域名场景确认表单中CSRF标签的位置
确保{% csrf_token %}标签位于<form>标签内部,且表单的提交方法为POST,render方法没有修改request对象的CSRF相关属性。
内容的提问来源于stack exchange,提问作者Bai Lin Zhu

