Джанго не увеличивает количество

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

models.py

 class Item(Visits, models.Model):
        title = models.CharField(max_length=150)
        price =  models.IntegerField(default=1000)
        image = models.ImageField(upload_to='pictures', default='static/images/man.png')
        description = models.TextField(default="Item")
        visits = models.IntegerField(default=0)
       

class OrderItem(models.Model):
    order_item = models.ForeignKey(Item, on_delete=CASCADE, null=True)
    quantity = models.IntegerField(default=1)

class Cart(models.Model):
    order_user = models.OneToOneField(User, on_delete=CASCADE)
    order_items = models.ManyToManyField(OrderItem)
    ordered = models.BooleanField(default=False)
    total = models.IntegerField(default=0, help_text="100 = 1EUR")

views.py

def post(self, request, pk):
        if 'buy' in request.POST:
            item = get_object_or_404(Item, id=pk)
            item_quantity = request.POST.get('quantity')
            orderItem, created = OrderItem.objects.get_or_create(order_item=item)
            cart, created = Cart.objects.get_or_create(order_user=request.user)
            cart.save()
            if Cart.objects.filter(order_items=orderItem).exists():
                orderItem.quantity += 1
            cart.order_items.add(orderItem)
            cart.save()
            return HttpResponse('Items added to the database')

   

Такое моделирование выглядит довольно странно. Обычно OrderItem должен быть моделью перехода [wiki] между Item и Cart, так что объект выглядит следующим образом:

class Item(Visits, models.Model):
    # ⋮

class OrderItem(models.Model):
    item = models.ForeignKey(Item, on_delete=CASCADE, null=True)
    cart = models.ForeignKey('Cart', on_delete=CASCADE)
    quantity = models.IntegerField(default=1)

class Cart(models.Model):
    order_user = models.ForeignKey(User, on_delete=CASCADE)
    order_items = models.ManyToManyField(
        Item,
        related_name='carts',
        through=OrderItem
    )
    ordered = models.BooleanField(default=False)
    total = models.IntegerField(default=0, help_text="100 = 1EUR")

Затем мы можем получить текущую активную Cart или создать ее, если такой Cart записи нет:

cart, __ = Cart.objects.get_or_create(
    user=request.user,
    ordered=False
)

и мы можем добавить что-то в эту корзину с помощью:

from django.db.models import F

orderitem, created = OrderItem.objects.get_or_create(
    cart=cart,
    item_id=pk
)
if not created:
    orderitem.quantity = F('quantity') + 1
    orderitem.save(force_update=True, update_fields=['quantity'])

Таким образом, вид выглядит следующим образом:

def post(self, request, pk):
    if 'buy' in request.POST:
        cart, __ = Cart.objects.get_or_create(
            user=request.user,
            ordered=False
        )
        orderitem, created = OrderItem.objects.get_or_create(
            cart=cart,
            item_id=pk
        )
        if not created:
            orderitem.quantity = F('quantity') + 1
            orderitem.save(force_update=True, update_fields=['quantity'])
        return redirect('name-of-some-view')

или если количество может быть увеличено с помощью параметра:

def post(self, request, pk):
    if 'buy' in request.POST:
        cart, __ = Cart.objects.get_or_create(
            user=request.user,
            ordered=False
        )
        quantity = request.POST.get('quantity')
        orderitem, created = OrderItem.objects.get_or_create(
            cart=cart,
            item_id=pk,
            defaults={'quantity': quantity}
        )
        if not created:
            orderitem.quantity = F('quantity') + quantity
            orderitem.save(force_update=True, update_fields=['quantity'])
        return redirect('name-of-some-view')

Примечание: В случае успешного POST запроса, вы должны сделать redirect. [Django-doc] для реализации паттерна Post/Redirect/Get [wiki]. Это позволяет избежать повторения POST-запроса, когда пользователь обновляет браузер. браузер.

Вернуться на верх