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

Django开发电商购物车功能触发MultipleObjectsReturned错误如何解决

问题修复方案

错误根因

  • get_or_create方法参数使用错误:Item.objects.get_or_create(Item)没有传递任何查询过滤条件,等同于查询所有Item对象,当数据库中存在多条Item记录时就会抛出MultipleObjectsReturned异常。
  • 视图逻辑存在多处与模型定义不匹配的问题:Order模型不存在item、quantity字段,错误将OrderItem的属性写在了Order上。
  • OrderItem.objects.get_or_create(active=True)同样没有关联对应商品,也会触发多返回值报错,且原OrderItem模型根本没有定义active字段。
  • 模型定义缩进错误:Order类错误定义为OrderItem的内部类,二者应为同级模型。

修复步骤

第一步:修正模型定义

调整models.py的结构和必要字段:

from django.db import models
from django.contrib.auth.models import User
from django.db.models import CASCADE

# 原有Item模型示例,可保留你原有字段
class Item(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=11, decimal_places=2)
    # slug为可选字段,非必须添加

class OrderItem(models.Model):
    order_item = models.ForeignKey(Item, on_delete=CASCADE, null=True)
    quantity = models.IntegerField(default=1)
    # 新增用户、下单状态字段,区分不同用户的未结算订单项
    user = models.ForeignKey(User, on_delete=CASCADE, null=True)
    ordered = models.BooleanField(default=False)

# 调整缩进,改为和OrderItem同级的类
class Order(models.Model):
    order_user = models.ForeignKey(User, on_delete=CASCADE)
    order_items = models.ManyToManyField(OrderItem)
    ordered = models.BooleanField(default=False)
    total = models.DecimalField(default=0.00, decimal_places=2, max_digits=11)

第二步:配置URL传递商品标识

修改urls.py,给加购接口传递商品ID参数:

path('add-to-cart/<int:item_id>/', add_to_cart, name='add_to_cart')

第三步:修正视图逻辑

重写add_to_cart视图,符合Django ORM的查询规则:

@login_required
def add_to_cart(request, item_id, *args, **kwargs):
    # 先查询指定商品,不存在直接返回404
    item = Item.objects.get(id=item_id)
    # 获取或创建当前用户未下单的对应商品订单项
    order_item, created = OrderItem.objects.get_or_create(
        order_item=item,
        user=request.user,
        ordered=False
    )
    # 查询当前用户未结算的购物车订单
    order_qs = Order.objects.filter(order_user=request.user, ordered=False)
    if order_qs.exists():
        order = order_qs.first()
        # 判断商品是否已在购物车内
        if order.order_items.filter(order_item__id=item_id).exists():
            # 已存在则数量+1
            order_item.quantity += 1
            order_item.save()
        else:
            # 不存在则新增订单项到订单
            order.order_items.add(order_item)
    else:
        # 无未结算订单则新建订单并加入订单项
        order = Order.objects.create(order_user=request.user)
        order.order_items.add(order_item)
    messages.success(request, "Cart updated!")
    return redirect('cart-page')

关于SlugField的疑问

不需要强制创建SlugField,使用商品ID作为查询条件完全可以满足需求。SlugField一般用于优化URL可读性,如果你希望URL展示为/add-to-cart/apple-iphone-14而非/add-to-cart/123可以添加,添加后只需将视图中的查询条件改为Item.objects.get(slug=传入的slug参数)即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:39:03