Множественные объекты, возвращенные в /cart/ в Django

#python #python-3.x #django #django-models #django-views

#python #python-3.x #django #django-модели #django-просмотры

Вопрос:

я новичок, и я получаю эту ошибку «Значение исключения: 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)
 

Спасибо.

Ответ №1:

Приведенная выше ошибка указывает на то, что в базе данных имеется более одной записи, связанной с конкретным параметром, который вы передали при запросе с помощью get()

Комментарии:

1. Попробуйте использовать filter

Ответ №2:

Ответственная строка за эту ошибку

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

поскольку у вас не было никаких ограничений, основанных на этом фильтре, и этот запрос вернул более одного объекта, и поскольку get должен возвращать только один объект, в этой строке был вызван MultipleObjectReturned тип ошибки. Поэтому, если вы хотите использовать get_or_create manager, убедитесь, что этот фильтр возвращает только один объект (установив ограничения базы данных и т. Д.). Другой способ — изменить эту строку на что-то вроде:

 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 здесь .

Ответ №3:

get возвращает один объект и принимает один параметр, filter возвращает повторяющийся набор запросов объектов и может принимать несколько параметров (например, сделанный вами запрос)

Ответ №4:

ваш запрос Order.objects.get_or_create() будет работать только для одной записи. Используется для предотвращения создания повторяющихся записей. Если вы хотите запросить несколько записей, вы можете использовать Order.objects.filter() или Order.objects.filter().get_or_create() с помощью Q объектов.

Ответ №5:

Возможно, я ошибаюсь, но ниже приведено мое понимание. Вы не упомянули, чего именно вы пытаетесь достичь, и этот факт усугубляет проблему.

get_or_create() — это функция, предназначенная в первую очередь для поиска, и она создаст запись, только если не сможет ее найти. Смотрите ниже из официальных документов .

Удобный метод для поиска объекта с заданными параметрами kwargs (может быть пустым, если ваша модель имеет значения по умолчанию для всех полей), создавая его при необходимости.

Так что, вероятно, в вашем случае метод get завершается успешно (и нет необходимости создавать, и, следовательно, он не переходит к этапу создания), но метод get возвращает более одного элемента. Это связано с тем, что у «конкретного клиента» есть более одной записи, в которой значение «complete» равно false. См. Официальные документы снова по ссылке выше.

Если найдено несколько объектов, 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)