将商品从购物车中删除后,无法将其添加到购物车中

问题描述 投票:0回答:1

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

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>
python django python-2.7 python-3.7
1个回答
0
投票

我不太清楚问题出在哪里,但是您可以更改很多事情,这会使您的应用程序更容易理解和更强大。

首先,您的数据模型可能需要一些改进。 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")
© www.soinside.com 2019 - 2024. All rights reserved.