0

I want to override the save method in order to

  1. update quantity if the cart_item already exists
  2. insert new entry if the cart_item does not already exists

but every time after the save method it gets stuck in infinite loop

class Cart(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid4)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self) -> str:
        return str(self.id)

class CartItem(models.Model):
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE, related_name='items')
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()

    def __str__(self) -> str:
        return self.product.name

    def save(self, *args, **kwargs):
        try:
            cart_item = CartItem.objects.get(cart_id=self.cart.id, product_id=self.product.id)
            cart_item.quantity += self.quantity
            pprint(cart_item)
            cart_item.save() #after this line goes into infinite loop
        except CartItem.DoesNotExist:
            super().save(*args, **kwargs) #after this line goes into infinite loop
            pprint("-------------------------here")
``
antoninislam
  • 117
  • 1
  • 2
  • 9
  • Have you considered using `objects.update_or_create`? – Lewis Nov 26 '21 at 18:48
  • Even if I use objects.update_or_create method. I will still have to do most of the things from the above code because I have to calculate the quantity using new and old data. – antoninislam Nov 27 '21 at 11:48

1 Answers1

0
def save(self, *args, **kwargs):
    if self._state.adding:
        try:
            cart_item = CartItem.objects.get(cart_id=self.cart.id, product_id=self.product.id)
            quantity = cart_item.quantity + self.quantity              
            CartItem.objects.filter(pk=cart_item.id).update(quantity=quantity)
        except CartItem.DoesNotExist:
            super(CartItem, self).save(*args, **kwargs)
    else:
        super(CartItem, self).save(*args, **kwargs)

Using the above code I'm able to achieve what I wanted. Save() function is called for both insert and update and I only wanted to alter the inserting behavior so in order to check what operation is performing, I took help from this page. And if I update using the model's update() method it doesn't go into an infinite loop ref.

antoninislam
  • 117
  • 1
  • 2
  • 9