能否手动向Django的gettext()传入语言代码实现指定语言翻译?
结论
完全可以直接用数据库里存的用户语言代码指定加载对应翻译,不需要非得从Cookie、URL、会话这些常规渠道读语言选择,这个方案是可行的。
实现流程
- 先对齐语言码规则
数据库存储的语言代码必须和本地多语言文件的命名一一对应,比如存zh-CN就对应简体中文语言包、存ja-JP就对应日语语言包,别出现数据库写chinese但文件叫zh-CN这种不匹配的问题,不然会加载失败。 - 在请求前置层拉取用户语言配置
写个请求中间件/拦截器,请求进来之后先拿到当前操作的用户ID,查数据库读出这个用户存的语言码,把这个值塞到当前请求的上下文对象里就行,别存全局变量,不然多用户并发的时候会串配置。 - 动态切换翻译器的语言包
所有后端i18n类库都支持手动指定当前使用的语言,你在业务里要拿翻译结果之前,把i18n实例的语言设置成刚才从请求上下文里拿到的用户语言码,再调用翻译方法就能拿到对应语言的文本。通用逻辑参考下面的伪代码:
// 请求拦截器逻辑 async function authInterceptor(req, res, next) { const currentUserId = getUserIdFromToken(req) // 查库拿用户配置的语言 const userLang = await userConfigRepo.getLangByUserId(currentUserId) // 挂载到当前请求上下文,全链路可用 req.ctx.lang = userLang || 'en-US' // 这里给默认值做兜底 next() } // 业务中调用翻译 function getWelcomeText(req) { // 手动指定当前翻译用的语言 i18n.locale = req.ctx.lang // 传入翻译key拿对应语言的文本 return i18n.t('user.welcome') }
- 做好降级兜底
一定要配置默认语言,比如默认用英文。如果查库拿到的语言码不存在、对应语言文件里找不到要翻译的key,就自动回退到默认语言,别把原始的翻译key直接返回给用户。
踩坑提醒
- 别每次调用翻译都去查一次数据库,在请求进来的时候查一次挂在上下文里就行,整个请求生命周期复用这个值,减少不必要的DB开销。
- 别把语言码存在进程级的全局变量里,多实例部署或者高并发场景下,很容易出现A用户的语言配置覆盖B用户的问题,必须把语言配置和当前请求绑定。
- 翻译内容尽量存在本地的独立语言文件(JSON/YAML格式都可以)里,别把翻译字符串存在数据库,后续更新、校对翻译的成本会低很多。
内容的提问来源于stack exchange,提问作者lr_optim
相关产品推荐
相关产品推荐

