【问题标题】:Adding item to cart do not work properly after removing that same item from cart从购物车中删除同一商品后,将商品添加到购物车后无法正常工作
【发布时间】:2020-03-20 11:50:05
【问题描述】:

从购物车中删除相同商品后,我在将商品添加到购物车时遇到问题。当将商品添加到购物车并从购物车中删除该商品时,当我尝试将其再次添加到购物车中时,该商品不会显示在购物车中。当我从管理面板中删除该项目时,该项目只能再次添加到购物车中。

模型.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>

【问题讨论】:

  • 有人可以帮我解决这个问题吗?

标签: python django python-2.7 python-3.7


【解决方案1】:

我不太确定问题出在哪里,但是您可以更改许多内容,以使您的应用程序更易于理解且更健壮。

首先,您的数据模型可以进行一些改进。 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")

【讨论】:

  • 谢谢你,我会试试的。但是我的代码对我来说效果很好,问题是当我将衬衫添加到购物车时,然后我从购物车中取出衬衫,当我再次尝试将衬衫添加到购物车时,它不会添加到购物车中。我希望它很清楚。
  • @Hi3e 你的代码很适合你,除非它不能,然后你不知道为什么它不能。这里有两个问题,(i)代码没有产生正确的结果,(ii)你不知道为什么它失败了。蒂姆给了你一个解决方案。您可能应该详细研究他的代码,因为它修复了您的代码的许多问题......
  • 是的,这就是我现在要做的,我正在弄清楚为什么从购物车中删除相同的商品后不会添加到购物车。
  • 我终于解决了这个问题,这只是一个缩进问题。感谢您的提示。
猜你喜欢
  • 1970-01-01
  • 2020-01-14
  • 2013-10-17
  • 2021-12-20
  • 2015-07-05
  • 2016-12-19
  • 1970-01-01
相关资源
最近更新 更多