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

如何实现未授权访客添加商品至购物车?解决Django 404错误

解决访客添加商品到购物车时的404错误

问题根源

出现No Session matches the given query的404错误,核心原因有三点:

  • 调用request.session.create()后,Django仅生成session_key,但未立刻将Session对象写入数据库,此时用get_object_or_404(Session, ...)会找不到对应记录
  • CartPage视图直接用get_object_or_404获取购物车,访客可能还未创建购物车,触发404
  • Cart模型中同时存在items多对多关联和CartItem的外键关联,造成逻辑冗余与冲突

分步修复

1. 修复shop/views.py的add_to_cart方法

调整Session获取逻辑,确保数据库中存在对应Session记录,同时优化商品获取的安全性:

def add_to_cart(self, request, wine_slug):
    session_key = request.session.session_key
    if not session_key:
        request.session.create()
        session_key = request.session.session_key
    
    # 确保数据库中存在该Session记录
    session, _ = Session.objects.get_or_create(session_key=session_key)
    # 用get_object_or_404处理商品不存在的场景
    product = get_object_or_404(Wine, slug=wine_slug)

    cart, created = Cart.objects.get_or_create(session=session)
    cart_item, item_created = CartItem.objects.get_or_create(cart_items=cart, product=product)
    cart_item.quantity += 1
    cart_item.save()

    return redirect('cart')

2. 修复orders/views.py的CartPage视图

允许访客自动创建购物车,避免直接使用get_object_or_404导致的404:

class CartPage(View):
    template = 'orders/cart.html'

    def get(self, request):
        session_key = request.session.session_key
        session = Session.objects.filter(session_key=session_key).first() if session_key else None
        
        # 获取或创建当前会话对应的购物车
        cart, created = Cart.objects.get_or_create(session=session)
        items = CartItem.objects.filter(cart_items=cart)

        def item_total():
            summ = 0.0
            for each in items:
                summ += each.product.price * each.quantity
            return summ

        context = {
            'cart': cart,
            'item': items,
            'item_total': item_total()
        }
        return render(request, self.template, context)

3. 清理orders/models.py的冗余关联

移除Cart模型中的items字段,因为CartItem已通过外键关联到Cart,无需重复关联:

class Cart(models.Model):
    session = models.ForeignKey(Session, null=True, blank=True, on_delete=models.CASCADE)
    date_generation = models.DateField(auto_now=True)

    def __str__(self):
        return str(self.date_generation)


class CartItem(models.Model):
    cart_items = models.ForeignKey(Cart, on_delete=models.CASCADE)
    product = models.ForeignKey(Wine, on_delete=models.PROTECT)
    quantity = models.IntegerField(default=0)

    def __str__(self):
        return str(self.pk)

额外说明

  • 访客的购物车会通过Session关联,Session过期后,购物车数据会保留在数据库中,可通过定时任务清理过期Session对应的Cart
  • 若需实现用户登录后合并访客购物车,可在用户登录信号中处理Cart的关联转移

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:41:23