PAYATHON 2026

Flask 删除 session 购物车条目后,为什么重定向仍显示旧数据?

数据小陈

原因:列表变了,但 session 没有被标记为已修改

使用 Flask 默认的 cookie session 时,del session['cart'][item_index] 会直接修改 session 内部的列表。Flask 不会自动将这类嵌套对象的原地修改标记为 session 修改,因此 session.modified 不会被设为 True。

当前请求中打印出的列表长度已经变成 2,但如果没有其他操作触发 session 保存,响应就不会把修改后的数据写回浏览器的 session cookie。重定向后的请求仍携带旧 cookie,读到的列表长度还是 3。

这种情况下,需要让 session 的修改被保存,无需额外向 /shopping_cart 传递购物车数据。

解决方法:删除后设置 session.modified

在删除操作后、返回重定向响应前,加上:

session.modified = True

修正购物车路由并整理缩进后,代码可以写成:

@app.route('/remove_item/<int:item_index>', methods=['POST'])
def remove_item(item_index):
    del session['cart'][item_index]
    session.modified = True
    return redirect(url_for('shopping_cart'))


@app.route('/shopping_cart', methods=['GET', 'POST'])
def shopping_cart():
    return render_template('shopping_cart.html')

这里假定 session['cart'] 已存在且是列表,item_index 也在有效范围内。删除路由只允许 POST 请求,因此函数内无需再次判断 request.method。

Flask 会在处理重定向响应时保存已修改的 session。浏览器收到更新后的 cookie,再请求 /shopping_cart 时,视图就能读到删除后的列表。

另一种方法:重新赋值给 session

也可以先复制列表,删除条目后再把结果赋回 session:

@app.route('/remove_item/<int:item_index>', methods=['POST'])
def remove_item(item_index):
    cart = list(session['cart'])
    del cart[item_index]
    session['cart'] = cart
    return redirect(url_for('shopping_cart'))

session['cart'] = cart 对 session 的顶层键赋值,会自动标记修改,因此无需再设置 session.modified = True。两种写法任选一种即可。

需要一起检查的地方

原始示例中的 @app.route('shopping_cart', ...) 缺少前导 /,应写成 @app.route('/shopping_cart', ...);函数体也需要正确缩进。这些问题需要修正,但与嵌套列表修改未被自动追踪是独立的。

实际处理请求时,还应检查购物车是否存在、索引是否越界,避免触发 KeyError 或 IndexError。如果使用自定义 session 实现,修改追踪和保存行为需要以该实现为准。

备注:内容仅供参考。