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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:50:23