Django会话变量异常:新增浏览记录加载新页面后丢失
解决Django会话中「最近浏览」条目丢失问题
问题描述
在网站首页实现「最近浏览」板块时,遇到会话数据丢失问题:在item视图中向request.session["recently-viewed"]追加商品ID后,切换到其他页面,刚添加的条目就会消失。
当前views.py代码:
def item(request, item_id): if "recently-viewed" not in request.session: request.session["recently-viewed"] = [item_id] else: request.session["recently-viewed"].append(item_id)
现象:
- 处于
item视图时,request.session["recently-viewed"]的值为["item1", "item2"] - 加载其他页面后,该变量值变为
["item1"]
需求:无需使用JavaScript,仅通过后端代码实现会话数据持久化,让「最近浏览」列表在页面切换后保持完整。
问题原因
Django的会话机制默认仅在直接修改会话字典的顶层键值时,才会标记会话为"已修改"并保存到后端存储。直接对会话中已存在的列表执行append操作时,Django无法检测到这个修改,导致新添加的条目不会被持久化。
解决方案
提供两种后端实现方式:
方式一:显式标记会话已修改
修改列表后,手动设置request.session.modified = True,告知Django会话数据已更新需要保存:
def item(request, item_id): if "recently-viewed" not in request.session: request.session["recently-viewed"] = [item_id] else: request.session["recently-viewed"].append(item_id) # 显式标记会话已修改 request.session.modified = True
方式二:重新赋值列表(更稳妥)
先取出列表,修改后重新赋值给会话键,让Django检测到顶层键的变化,自动触发保存:
def item(request, item_id): recently_viewed = request.session.get("recently-viewed", []) # 可选:避免重复添加同一商品ID if item_id not in recently_viewed: recently_viewed.append(item_id) # 可选:限制最近浏览条目数量,比如仅保留10条 if len(recently_viewed) > 10: recently_viewed.pop(0) # 重新赋值触发会话保存 request.session["recently-viewed"] = recently_viewed
额外优化建议
- 增加去重逻辑:防止同一商品ID重复出现在「最近浏览」列表中
- 设置列表长度上限:避免列表无限增长,影响系统性能
- 检查会话配置:确认
settings.py中的SESSION_ENGINE配置正常(默认django.contrib.sessions.backends.db为可靠选项)
内容的提问来源于stack exchange,提问作者logan_9997
相关产品推荐
相关产品推荐

