You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django自定义语言切换后get_language()返回英文的问题求助

问题核心根源

你当前的自定义语言切换逻辑存在三个和Django语言机制不匹配的问题,直接导致跨请求的语言状态丢失:

  • activate(lang_code) 仅对当前正在处理的请求线程生效,请求处理完成后,线程本地存储的语言状态会被自动清空,完全不会留存到后续独立发起的其他请求中
  • 你手动将语言值写入session的操作,没有对齐Django LocaleMiddleware 的默认解析链路:中间件在每次新请求进来时,会按照“URL i18n前缀→Cookie存储的语言值→session存储的语言值→浏览器Accept-Language请求头→项目默认语言”的顺序解析当前语言,而你的接口返回时根本没有将语言值写入对应Cookie
  • 你看到第一次切换后页面刷新正常,是因为那次刷新是在语言写入session之后的同会话请求,后续“加载更多帖子”这类独立ajax请求如果没有正确携带Cookie、或者session读取链路被阻断,就会直接回退到默认的英文设置。
可落地的解决步骤
  • 调整change_lang视图逻辑,不要依赖手动临时激活的状态,补上跨请求语言持久化的核心逻辑,和Django官方语言设置逻辑对齐:
    from django.conf import settings
    from django.http import JsonResponse
    from django.utils.translation import activate
    from django.views.i18n import LANGUAGE_COOKIE_NAME
    
    def change_lang(request):
        lang_code = request.GET.get('language')
        # 提前校验语言是否在项目支持的列表里,避免恶意传参
        supported_languages = {lang[0] for lang in settings.LANGUAGES}
        if lang_code not in supported_languages:
            return JsonResponse({"status": "error", "msg": "Unsupported language option"})
        
        # 激活当前请求的语言
        activate(lang_code)
        # 同步将语言值写入session,适配中间件的session读取逻辑
        if hasattr(request, 'session'):
            request.session[LANGUAGE_COOKIE_NAME] = lang_code
        
        # 生成响应,将语言值写入全局生效的Cookie——这是跨请求保留语言状态的核心
        response = JsonResponse({"status": "OK"})
        response.set_cookie(
            LANGUAGE_COOKIE_NAME,
            lang_code,
            max_age=settings.LANGUAGE_COOKIE_AGE,
            path=settings.LANGUAGE_COOKIE_PATH,
            domain=settings.LANGUAGE_COOKIE_DOMAIN,
            secure=settings.LANGUAGE_COOKIE_SECURE,
            httponly=settings.LANGUAGE_COOKIE_HTTPONLY,
            samesite=settings.LANGUAGE_COOKIE_SAMESITE,
        )
        return response
    
  • 检查项目中间件的配置顺序,确保LocaleMiddleware的位置正确:必须放在SessionMiddleware之后、CommonMiddleware之前,否则中间件读不到session数据,也无法正确解析/写入语言状态。正确的顺序参考:
    MIDDLEWARE = [
        # 框架内置的基础中间件
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        # 语言解析中间件必须在Session之后、Common之前
        'django.middleware.locale.LocaleMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 其他业务中间件
    ]
    
  • 排查前端发起“加载更多帖子”这类ajax请求的配置:如果是同源请求,确认没有故意拦截请求Cookie的携带;如果是跨域请求,需要配置withCredentials: true,确保请求能把之前存的语言Cookie带到后端,不然哪怕Cookie写入成功,后端读不到也会回退到默认语言。
  • 业务代码里获取当前生效语言时,不要直接调用get_language(),优先读request.LANGUAGE_CODE——这个值是LocaleMiddleware在请求初始化阶段就解析完成的,是当前请求真正生效的语言,能避免多线程环境下本地变量污染导致的取值错误。

内容的提问来源于stack exchange,提问作者Pypax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 15:45:10