在我的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)
感谢您的帮助!
答案 0 :(得分:1)
get_or_create
函数将尝试使用 all 传递的确切属性来获取CartItem
。在您的情况下,您尝试匹配product
,item_cost
,quantity
和all_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定义的角度避免在这种情况下创建多个条目,但是您也必须在代码中处理相同的情况