【问题标题】:MultipleObjectsReturned at /cart/ in DjangoMultipleObjectsReturned at /cart/ in Django
【发布时间】:2021-03-25 02:14:57
【问题描述】:

我是初学者,我收到此错误“异常值:get() 返回了多个订单 - 它返回了 2!”

views.py

def cart(request):
    customer=request.user.customer
    order,created=Order.objects.get_or_create(customer=customer,complete=False)
    items=order.orderitem_set.all()
    context={
        'items':items
    }
    return render(request, 'catalog/cart.html',context)

models.py

class Order(models.Model):
    customer=models.ForeignKey(Customer,on_delete=models.SET_NULL, blank=True, null=True)
    date_orderd=models.DateTimeField(auto_now_add=True)
    complete=models.BooleanField(default=False, null=True, blank=False)
    transaction_id=models.CharField(max_length=200, null=True)

    def __str__(self):
        return str(self.id)
class OrderItem(models.Model):
    product=models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
    order=models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
    quantity=models.IntegerField(default=0, null=True, blank=True)
    date_added=models.DateTimeField(auto_now_add=True)

谢谢。

【问题讨论】:

    标签: python python-3.x django django-models django-views


    【解决方案1】:

    上述错误表明你在使用get()查询时传递的特定参数相关的数据库中有不止一条记录

    【讨论】:

    • 尝试使用过滤器
    【解决方案2】:

    您的查询Order.objects.get_or_create() 仅适用于一条记录。它用于防止创建重复记录。如果要查询多条记录,可以通过Q objects 使用Order.objects.filter()Order.objects.filter().get_or_create()

    【讨论】:

      【解决方案3】:

      这个错误的责任线是

      order,created=Order.objects.get_or_create(customer=customer,complete=False)
      

      因为您没有基于此过滤器的任何约束,并且此查询返回了多个对象,并且由于 get 必须只返回一个对象,因此该行引发了 MultipleObjectReturned 错误类型。因此,如果您想使用get_or_create 管理器,请确保此过滤器仅返回一个对象(通过设置数据库约束等)。另一种方法是将此行更改为:

      order = Order.objects.filter(customer=customer,complete=False).first() # or .last() based on your requirements
      if not order:
          order = Order.objects.create(customer=customer,complete=False)
      

      您还可以阅读有关get_or_create here 的更多信息。

      【讨论】:

        【解决方案4】:

        get 返回单个对象并接受 一个 参数,filter 返回对象的可迭代查询集并且可以接受多个参数(如您所做的查询)

        【讨论】:

          【解决方案5】:

          我可能错了,但以下是我的理解。你没有提到你到底想达到什么目标,这个事实使问题更加复杂。

          get_or_create() 是一个主要用于查找的函数,只有在找不到记录时才会创建记录。 见下文来自官方docs

          一种使用给定 kwargs 查找对象的便捷方法(如果您的模型具有所有字段的默认值,则可能为空),如有必要,创建一个。

          因此,在您的情况下,get 方法可能成功(并且不需要创建,因此它不会进入创建步骤),但 get 方法返回多个项目。这是因为,“特定客户”有多个记录“完整”提交等于假。在上面的链接中再次查看官方文档。

          如果找到多个对象,get_or_create() 会引发 MultipleObjectsReturned。

          您的表中唯一唯一的句柄可能是 date_orderd(如果设置正确,也可能是 transaction_id)。但是,您没有在 get_or_create() 中使用此字段。

          如果你想创建单个对象,那么只需使用 create()。另外我认为你在下一行(下面)有一个错误,因为基于代码共享的 orderitem_set 不在订单表中。

          items=order.orderitem_set.all()
          

          视图中稍作改动的代码如下

          def cart(request):
              customer=request.user.customer
              order,created=Order.objects.create(customer=customer,complete=False)
              items=Order.objects.all()
              context={
                  'items':items
              }
              return render(request, 'catalog/cart.html',context)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-06-01
            • 2020-02-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-22
            • 2017-11-05
            • 1970-01-01
            相关资源
            最近更新 更多