我从购物车中删除同一项目后,将项目添加到购物车时遇到问题。当项目添加到购物车中并且从购物车中删除该项目时,当我尝试再次在购物车中添加该项目时,该项目不会显示在购物车中。当我从管理面板中删除该商品时,它只能再次添加到购物车中。
Models.py:
class Item(models.Model):
title = models.CharField(max_length=250)
image = models.ImageField(null=True)
price = models.IntegerField()
old_price = models.IntegerField(null=True, blank=True)
description = HTMLField()
category = models.CharField(choices=CATEGORY_CHOICES, max_length=2)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = AutoSlugField(populate_from='title')
timestamp = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=True)
class Meta:
ordering = ['-timestamp']
db_table = 'items'
verbose_name_plural = 'Items'
def __str__(self):
return self.title
class OrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
ordered = models.BooleanField(default=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
variation = models.ManyToManyField(Variation)
def __str__(self):
return f"{self.quantity} of {self.item.title}"
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)
billing_address = models.ForeignKey('BillingAddress', on_delete=models.SET_NULL, blank=True, null=True)
def __str__(self):
return self.user.username
Views.py:
@login_required
def add_to_cart(request, slug):
item = get_object_or_404(Item, slug=slug)
item_var = [] #item variation
if request.method == 'POST':
print(request.POST)
qty = request.POST['quantity']
for items in request.POST:
key = items
val = request.POST[key]
print(key,val)
try:
v = Variation.objects.get(
item=item,
category__iexact=key,
title__iexact=val
)
item_var.append(v)
except:
pass
order_item_qs = OrderItem.objects.filter(
item=item,
user=request.user,
ordered=False
)
print(order_item_qs)
if len(item_var) > 0:
for items in item_var:
order_item_qs = order_item_qs.filter(
variation__exact=items,
)
if order_item_qs.exists():
order_item = order_item_qs.first()
order_item.quantity = qty
order_item.save()
print(order_item_qs)
else:
order_item = OrderItem.objects.create(
item=item,
user=request.user,
ordered=False
)
order_item.variation.add(*item_var)
order_item.quantity = qty
order_item.save()
print(order_item)
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 not order.items.filter(item__id=order_item.id).exists():
order.items.quantity = qty
order.items.add(order_item)
messages.info(request, "This item quantity was updated.")
return redirect("shop:order-summary")
else:
ordered_date = timezone.now()
order = Order.objects.create(user=request.user, ordered_date=ordered_date)
order.items.add(order_item)
messages.info(request, "This item was added to cart.")
return redirect("shop:order-summary")
@login_required
def remove_from_cart(request, slug):
id = request.POST.get('id', None) #retrieve id
print(id)
item = get_object_or_404(Item, slug=slug) #if no item found raise page not found
print(item)
obj_order_qs = Order.objects.filter(
user=request.user,
ordered=False
)
if obj_order_qs.exists():
order = obj_order_qs[0]
if order.items.filter(item__slug=item.slug).exists():
order_item = OrderItem.objects.filter(
id=id,
item=item,
user=request.user,
ordered=False
)[0]
order.items.remove(order_item)
messages.info(request, "This item was removed from cart.")
return redirect("shop:order-summary")
else:
messages.info(request, "This item was not in your cart.")
return redirect("shop:order-summary")
else:
messages.info(request, "You do not have an active order.")
return redirect("shop:order-summary")
模板:
<form action="{{ order_item.item.get_remove_from_cart_url }}" method="post">
{% csrf_token %}
<input name="id" type="hidden" value="{{ order_item.id }}" />
<input type="submit" value="Delete" />
</form>
我不太清楚问题出在哪里,但是您可以更改很多事情,这会使您的应用程序更容易理解和更强大。
首先,您的数据模型可能需要一些改进。 OrderItem
将仅分配给单个Order
,因此它应该具有要订购的外键。然后,您可以删除OrderItem.user,因为只有Order上的用户才可以访问它。 Item.slug应该是唯一的。
class Item(models.Model):
# The slug for every item should be unique since it's used in the URL.
slug = AutoSlugField(populate_from='title', unique=True)
class Order(models.Model):
# This is no longer necessary with the FK on OrderItem.
# items = models.ManyToManyField(OrderItem)
class OrderItem(models.Model):
# The user for the Order will be the same here. Normalizing your db makes authorization easier.
# user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="items")
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
variation = models.ManyToManyField(Variation)
def __str__(self):
return f"{self.quantity} of {self.item.title}"
然后您删除视图可能如下所示:
@login_required
def remove_from_cart(request, slug):
order_items = OrderItem.objects.select_related('order').filter(
order__user=request.user,
item__slug=slug
)
order_item = get_object_or_404(
order_items,
id=request.POST.get('id', None),
)
# I'd recommend just filtering these out in the .filter() above
if order_item.order.ordered:
messages.info(request, "This order is no longer active.")
return redirect("shop:order-summary")
order_item.delete()
messages.info(request, "This item was removed from your cart.")
return redirect("shop:order-summary")
我也更新了您的添加到购物车视图:
@login_required
def add_to_cart(request, slug):
ordered_date = timezone.now()
order, created = Order.objects.get_or_create(user=request.user, ordered_date=ordered_date, ordered=False)
item = get_object_or_404(Item, slug=slug)
item_var = [] # item variation
if request.method == 'POST':
print(request.POST)
qty = request.POST['quantity']
for items in request.POST:
key = items
val = request.POST[key]
print(key, val)
try:
v = Variation.objects.get(
item=item,
category__iexact=key,
title__iexact=val
)
item_var.append(v)
except:
pass
order_item_qs = OrderItem.objects.filter(
order=order,
item=item,
)
print(order_item_qs)
if len(item_var) > 0:
for items in item_var:
order_item_qs = order_item_qs.filter(
variation__exact=items,
)
order_item = order_item_qs.first()
if order_item:
order_item.quantity = qty
order_item.save()
print(order_item)
messages.info(request, "This item quantity was updated.")
return redirect("shop:order-summary")
else:
order_item = OrderItem.objects.create(
item=item,
user=request.user,
ordered=False,
quantity=qty,
)
order_item.variation.add(*item_var)
order_item.save()
print(order_item)
messages.info(request, "This item was added to cart.")
return redirect("shop:order-summary")