简体   繁体   中英

Django Add To cart Function with UNIQUE constraint failed

I have an add-to-cart function that throws an error when It is triggered. The function works if a user uses the admin account, but when a user has a normal account, it shows the below error.

Views.py

@login_required
def add_to_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_item, created = OrderItem.objects.get_or_create(
        item=item,
        user=request.user,
        ordered=False,
    )
    order_qs = Order.objects.filter(user=request.user, ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        # check if the order item is in the order
        if order.items.filter(item__slug=item.slug).exists():
            order_item.quantity += 1
            order_item.save()

            order.save()
            messages.success(request, "This item was updated to your cart.")
        else:
            messages.success(request, "This item was added to your cart.")
            order.items.add(order_item)
            order.save()
    else:
        ordered_date = timezone.now()
        order = Order.objects.get_or_create(id=item.id,
            user=request.user, ordered_date=ordered_date)
        order.items.add(order_item)
        order.save()
        messages.success(request, "This item was added to your cart.")
    return redirect("product", slug=slug)

Models.py

class Item(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    price = models.FloatField()
    stored = models.DateTimeField(auto_now_add=True)
    item_quantity = models.IntegerField(default=1)
    img = models.ImageField(upload_to='images/')
    category = models.CharField(choices=CATEGORY_CHOICES, max_length=15)
    slug = models.SlugField(unique=True, default=uuid.uuid1)
    
    def __str__(self) -> str:
        return self.title
    
    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Item, self).save(*args, **kwargs)
    
    def get_absolute_url(self):
        return reverse("product", kwargs={"slug": self.slug})
    
    def get_add_to_cart_url(self):
        return reverse("add-to-cart", kwargs={
            'slug': self.slug
        })
    
    def get_remove_from_cart_url(self):
        return reverse("remove_from_cart", kwargs={
            'slug': self.slug
        })
        
    def get_add_single_item_to_cart_url(self):
        return reverse("add_single_item_to_cart", kwargs={
            'slug': self.slug
        })
    
    def get_remove_single_item_from_cart_url(self):
        return reverse("remove_single_item_from_cart", kwargs={
            'slug': self.slug
        })
        

class OrderItem(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                            on_delete=models.CASCADE)
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)
    ordered = models.BooleanField(default=False)
    
    def __str__(self):
        return f"{self.quantity} of {self.item.title}"
    
    def get_total_item_price(self):
        return self.quantity * self.item.price
    
    def get_final_price(self):
        return self.get_total_item_price()
    
    def get_quantity(self):
        return self.quantity
    
      
class Order(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    items = models.ManyToManyField(OrderItem)
    start_date = models.DateTimeField(auto_now_add=True)
    ordered_date = models.DateTimeField()
    ordered = models.BooleanField(default=False)
    total_price = models.FloatField(default=0)

    def __str__(self):
        return self.user.username
    
    def get_total(self):
        total = 0
        for order_item in self.items.all():
            total += order_item.get_final_price()
        return total
    
    def save(self, *args, **kwargs):
        total = 0
        self.total_price = self.get_total()
        return super().save(*args, **kwargs)

Error message:

IntegrityError at /add-to-cart/start-with-why/ UNIQUE constraint failed: ecommpage_order.id Request Method: GET Request URL: http://127.0.0.1:8000/add-to-cart/start-with-why/ Django Version: 3.1.7 Exception Type: IntegrityError Exception Value: UNIQUE constraint failed: ecommpage_order.id

You create an order with id=item.id , but that makes not much sense since the database normally dispatches the id. Especially since you set the id of the order, this means that it is likely that eventually the same id will be used.

You thus should remove

order = Order.objects.get_or_create(
    id=item.id,
    user=request.user,
    ordered_date=ordered_date
)

and simply create an Order and then add an item to that order:

order = Order.objects.get_or_create(
    user=request.user,
    ordered_date=ordered_date
)
orderorder_item

The modeling also looks a bit odd. Normally the quantity is stored in the junction table [wiki] . You can do that in Django by specifying a through=… model [Django-doc] .


Note : Django's DateTimeField [Django-doc] has a auto_now_add=… parameter [Django-doc] to work with timestamps. This will automatically assign the current datetime when creating the object, and mark it as non-editable ( editable=False ), such that it does not appear in ModelForm s by default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM