Django request.session无法保存数据,登录后获取会话报错
解决Django Session未保存及AttributeError问题
核心问题分析
AttributeError: 'NoneType' object has no attribute 'nombre' 说明你在尝试访问一个None对象的nombre属性,本质原因要么是Session中根本没存入nombre数据,要么是跨域/请求配置问题导致Session没有在前后端之间正确传递。
分步排查与解决
1. 确认登录视图正确写入Session
首先检查登录视图是否确实将数据存入了Session,且确保操作有效:
# Django 登录视图示例 from django.http import JsonResponse from django.contrib.auth import authenticate, login def login_view(request): if request.method == 'POST': # 根据实际请求方式解析参数(JSON/表单) import json data = json.loads(request.body) username = data.get('username') password = data.get('password') user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # 明确写入Session数据,确保user对象存在nombre字段 request.session['nombre'] = user.nombre # 强制标记Session为已修改,避免自动保存失效 request.session.modified = True return JsonResponse({'status': 'success'}) else: return JsonResponse({'status': 'error', 'msg': '登录失败'}, status=400)
- 确保Session相关配置正确:
# settings.py INSTALLED_APPS = [ # ... 'django.contrib.sessions', 'django.contrib.auth', # ... ] MIDDLEWARE = [ # ... 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # ... ]
2. 修复跨域请求的Session传递配置
如果React前端和Django后端跨域部署,必须配置请求携带Cookie,否则Session无法关联:
// React 登录请求示例 const handleLogin = async () => { // 先获取CSRF令牌(Django自动生成的隐藏字段) const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value; const loginRes = await fetch('/api/login', { method: 'POST', credentials: 'include', // 关键:强制携带Session Cookie headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken }, body: JSON.stringify({ username: 'your-username', password: 'your-password' }) }); // 获取Session的请求同样需要带credentials const sessionRes = await fetch('/api/get-session', { credentials: 'include' }); const sessionData = await sessionRes.json(); console.log(sessionData); }
Django端配合跨域配置(以django-cors-headers为例):
# settings.py INSTALLED_APPS = [ # ... 'corsheaders', # ... ] MIDDLEWARE = [ # 注意顺序:需在CommonMiddleware之前 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... ] CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_WHITELIST = [ "http://localhost:3000", # 你的React前端地址 ]
3. 修正GetSession视图的容错逻辑
避免直接访问可能为None的属性,先判断Session数据是否存在:
# Django 获取Session视图示例 def get_session_view(request): # 用get方法安全获取,不存在则返回None nombre = request.session.get('nombre') if not nombre: return JsonResponse({'error': 'Session未找到或已过期'}, status=401) return JsonResponse({'nombre': nombre})
错误示例(直接引发AttributeError):
# 错误:如果user是None,访问user.nombre会报错 user = request.session.get('user') return JsonResponse({'nombre': user.nombre})
4. 其他排查点
- 检查
SESSION_COOKIE_DOMAIN配置:开发环境下可设为'localhost',确保Cookie能被前端读取 - 打开浏览器开发者工具的Application > Cookies,确认是否存在
sessionidCookie,且域名与后端匹配 - 在登录和获取Session的视图中打印
request.session.session_key,验证两次请求是否使用同一个Session ID
内容的提问来源于stack exchange,提问作者Marzhal
相关产品推荐
相关产品推荐

