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

Flask中current_user列表属性无法持久修改问题求助

问题根源

你遇到的问题核心在于购物车数据没有持久化存储,且User类中的cart = []是类属性而非实例属性,同时每次请求的current_user都是从数据库重新加载的新实例:

  1. 你在delete_from_cart中修改的只是当前请求内存里的current_user.cart,既没保存到数据库,也没同步到会话(session);
  2. 跳转到checkout请求时,Flask-Login会重新从数据库查询用户,得到一个全新的User实例,之前的修改自然丢失。
解决方案

下面提供两种常用的解决思路,按需选择:

方案一:数据库持久化购物车(推荐,适合登录用户长期保存)

通过创建关联模型,将购物车数据存储到数据库,实现持久化。

1. 创建购物车项模型

class CartItem(db.Model):
    __tablename__ = 'cart_items'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Text, db.ForeignKey('users.user_id'), nullable=False)
    dish_id = db.Column(db.Integer, db.ForeignKey('dishes.dish_id'), nullable=False)
    quantity = db.Column(db.Integer, default=1)  # 支持商品数量统计

    # 关联关系
    user = db.relationship('User', back_populates='cart_items')
    dish = db.relationship('Dish')

2. 修改User类

移除原来的cart = [],添加关联关系和操作方法:

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    user_id = db.Column(db.Text, primary_key=True)
    password = db.Column(db.Text)
    roles = db.Column(db.String(length=25))
    stall_id = db.Column(db.Integer, db.ForeignKey('stalls.stall_id'), nullable=True)

    # 关联购物车项,删除用户时自动删除购物车
    cart_items = db.relationship('CartItem', back_populates='user', cascade='all, delete-orphan')

    def __init__(self, user_id, password, role):
        self.user_id = user_id
        self.password = password
        self.roles = role

    def get_id(self):
        return self.user_id

    # 快捷获取购物车中的商品列表
    @property
    def cart(self):
        return [item.dish for item in self.cart_items]

    # 添加商品到购物车(自动处理重复商品增加数量)
    def add_to_cart(self, dish):
        existing_item = next((item for item in self.cart_items if item.dish_id == dish.dish_id), None)
        if existing_item:
            existing_item.quantity += 1
        else:
            new_item = CartItem(user_id=self.user_id, dish_id=dish.dish_id)
            self.cart_items.append(new_item)
        db.session.commit()

    # 从购物车删除商品
    def remove_from_cart(self, dish_id):
        item_to_remove = next((item for item in self.cart_items if item.dish_id == dish_id), None)
        if item_to_remove:
            self.cart_items.remove(item_to_remove)
            db.session.commit()

3. 修改视图函数

添加商品:

@app.route('/add-to-cart/<int:picked_dish_id>', methods=['GET', 'POST'])
@login_required
def add_to_cart(picked_dish_id):
    dish = Dish.query.filter_by(dish_id=picked_dish_id).first()
    if dish:
        current_user.add_to_cart(dish)
        print(current_user.cart)
    return render_template('add_to_cart.html', dish=dish)

删除商品:

@app.route('/delete-from-cart/<int:dish_id>')
@login_required
def delete_from_cart(dish_id):
    print(current_user.cart)
    current_user.remove_from_cart(dish_id)
    print("Cart after deleting ", end='')
    print(current_user.cart)
    return redirect(url_for('checkout'))

checkout视图无需修改,current_user.cart仍可正常使用。

方案二:会话(Session)存储购物车(适合临时购物,不持久化)

利用Flask的session存储商品ID,每次请求从session中读取并查询商品。

1. 修改视图函数

添加商品:

@app.route('/add-to-cart/<int:picked_dish_id>', methods=['GET', 'POST'])
@login_required
def add_to_cart(picked_dish_id):
    dish = Dish.query.filter_by(dish_id=picked_dish_id).first()
    if dish:
        # 初始化session购物车
        if 'cart' not in session:
            session['cart'] = []
        # 避免重复添加(可选,根据需求调整)
        if picked_dish_id not in session['cart']:
            session['cart'].append(picked_dish_id)
        # 强制标记session修改,Flask默认检测不到列表类可变对象的变化
        session.modified = True
        print(session['cart'])
    return render_template('add_to_cart.html', dish=dish)

删除商品:

@app.route('/delete-from-cart/<int:dish_id>')
@login_required
def delete_from_cart(dish_id):
    if 'cart' in session:
        print(session['cart'])
        session['cart'] = [id for id in session['cart'] if id != dish_id]
        session.modified = True
        print("Cart after deleting ", end='')
        print(session['cart'])
    return redirect(url_for('checkout'))

checkout视图:

@app.route('/checkout')
@login_required
def checkout():
    cart_dishes = []
    if 'cart' in session:
        # 根据session中的ID查询商品
        cart_dishes = Dish.query.filter(Dish.dish_id.in_(session['cart'])).all()
    print("Cart in checkout: ", end='')
    print(cart_dishes)
    return render_template('checkout.html', cart=cart_dishes)

2. 注意事项

  • session默认存储在客户端cookie中,有大小限制,不适合存储大量商品;
  • 用户清除浏览器cookie后,购物车数据会丢失。

内容的提问来源于stack exchange,提问作者MisteryDush

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:30:52