Django设置Session变量问题:设置后获取值为None求助
Django Session变量设置后读取为None的问题排查
嘿,我之前也踩过类似的坑!结合你描述的情况,大概率是Django REST Framework(DRF)的默认配置或者跨域请求的细节没处理好,下面给你梳理几个常见原因和对应的解决办法:
最核心的原因:DRF API视图默认不启用Session认证
DRF的@api_view装饰的视图,默认是关闭Session支持的——毕竟API场景更常用token认证。所以你在login视图里设置了Session,但后续请求无法关联到同一个Session实例,自然读不到数据。
解决办法:给视图添加SessionAuthentication认证类
修改你的视图函数,引入并启用SessionAuthentication:
from rest_framework.authentication import SessionAuthentication from rest_framework.decorators import authentication_classes, api_view from rest_framework import status from rest_framework.response import Response import requests CORE_ADDRESS = "你的核心服务地址" @api_view(['POST']) @authentication_classes([SessionAuthentication]) # 开启Session认证支持 def login(request): if request.method == 'POST': response = requests.post(CORE_ADDRESS + 'login/', json=request.data) if response.status_code == 200: user_data = response.json() # 设置Session变量 request.session['user_info'] = user_data # 特殊场景下可手动触发保存(比如异步操作后) request.session.save() return Response({"message": "登录成功"}, status=status.HTTP_200_OK) else: return Response(response.json(), status=response.status_code) # 第二个需要读取Session的视图也要添加认证类 @api_view(['GET']) @authentication_classes([SessionAuthentication]) def get_user_session(request): # 读取Session变量 user_info = request.session.get('user_info', None) if user_info: return Response(user_info, status=status.HTTP_200_OK) else: return Response({"error": "未找到Session数据"}, status=status.HTTP_401_UNAUTHORIZED)
第二个高频原因:跨域请求未携带Session Cookie
如果你的前端和后端是跨域部署的(比如前端在localhost:3000,后端在localhost:8000),浏览器默认不会跨域发送Cookie,导致后端无法识别用户的Session。
解决办法:
- 后端配置CORS允许Credentials:
在settings.py里补充CORS相关配置:
INSTALLED_APPS = [ # ... 其他应用 'corsheaders', # 确保已安装corsheaders库 ] MIDDLEWARE = [ # ... 其他中间件 'corsheaders.middleware.CorsMiddleware', # 必须放在CommonMiddleware之前 'django.middleware.common.CommonMiddleware', # ... ] CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_WHITELIST = [ "http://localhost:3000", # 你的前端域名 # 其他需要允许的域名... ]
- 前端请求时开启Credentials:
比如用Axios的话:
axios.get('http://localhost:8000/get_user_session/', { withCredentials: true })
用Fetch API的话:
fetch('http://localhost:8000/get_user_session/', { credentials: 'include' })
其他需要检查的细节
- Session中间件是否存在:确保
settings.py的MIDDLEWARE列表里包含'django.contrib.sessions.middleware.SessionMiddleware',并且顺序在CommonMiddleware之前。 - Session手动保存:虽然Django通常会自动保存Session,但如果是在异步操作、异常捕获块等特殊流程中修改Session,可能需要手动调用
request.session.save()确保数据写入。
内容的提问来源于stack exchange,提问作者Denis Bellato
相关产品推荐
相关产品推荐

