Django创建新的购物车产品,而不是更新现有对象

时间:2019-08-05 15:11:39

标签: django django-views

在我的django商店中,我有一个添加到购物车的功能。但是,如果我将相同产品以不同的数量添加到购物车2次,则会创建2个不同的对象。我的代码有什么问题?

这是我的看法

def add_to_cart_view(request):
    cart = getting_or_creating_cart(request)
    product_slug = request.POST.get('product_slug')
    product = Product.objects.get(slug=product_slug)

    if request.method == "POST":
        form = CartAddProductForm(request.POST or None)
        if form.is_valid():
            quantity = form.cleaned_data['quantity']
            new_item, created = CartItem.objects.get_or_create(
                product=product,
                item_cost=product.price,
                quantity=quantity,
                all_items_cost=product.price*quantity,
            )
            if new_item.product.title == product.title:
                cart.items.add(new_item)
                cart.save()

            if not created:
                new_item.quantity += quantity
                new_item.save(force_update=True)
                cart.save()

    new_cart_total = 0.00
    for item in cart.items.all():
        new_cart_total += float(item.all_items_cost)
    cart.cart_total_cost = new_cart_total
    cart.save()

    return JsonResponse({
        'cart_total': cart.items.count()
        })

这是我的模特

class CartItem(models.Model):
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
    quantity = models.PositiveIntegerField(null=True, default=1)
    item_cost = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)
    all_items_cost = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)

    def __str__(self):
        return str(self.product.title)


class Cart(models.Model):
    items = models.ManyToManyField(CartItem, blank=True)
    cart_total_cost = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)

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

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

get_or_create函数将尝试使用 all 传递的确切属性来获取CartItem。在您的情况下,您尝试匹配productitem_costquantityall_items_cost。如果您将不同数量的同一产品传递给它,则该产品将不匹配,它将创建一个新的CartItem

查看documentation of get_or_create。创建新的product时,仅使用defaults进行查询,使用CartItem进行设置:

new_item, created = CartItem.objects.get_or_create(
            product=product,
            defaults = dict(
                item_cost=product.price,
                quantity=quantity,
                all_items_cost=product.price*quantity),
        )

答案 1 :(得分:1)

@dirkgroten提供了一个很好的答案,您也可以使用unique_together选项来防止创建重复条目 假设您在产品模型中有三个字段名称,尺寸,品牌 并且您不想创建任何具有相同名称,大小和品牌的新条目 您可以将其设置为

zoom

我个人不接受使用unique_together,但是肯定会从DB定义的角度避免在这种情况下创建多个条目,但是您也必须在代码中处理相同的情况