【问题标题】:Having trouble increasing product quantity when multiple of the same product are added to cart将多个相同产品添加到购物车时无法增加产品数量
【发布时间】:2019-11-15 22:53:25
【问题描述】:

Example Image Attachment

图片附件:当我尝试增加第二个项目的数量时,第一个项目的数量增加到2,而不是第二个项目的数量。

您可以观看我在这里上传的视频以更好地理解: https://web.facebook.com/groups/1378481325739503/permalink/2373521109568848/

在此处查看视图和模板:https://codeshare.io/GLp0Rg

型号:

class Item(models.Model):
    title = models.CharField(max_length=250)
    price = models.IntegerField()
    discount_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 = models.SlugField(unique=True,max_length=250)


    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("product-detail", kwargs={
            'slug': self.slug
        })
    def get_add_to_cart_url(self):
        return reverse("add-to-cart", kwargs={
            'slug': self.slug
        })
    def get_remove_from_cart_url(self):
        return reverse("remove-from-cart", kwargs={
            'slug': self.slug
        })

class VariationManager(models.Manager):
    def all(self):
        return super(VariationManager, self).filter(active=True)

    def sizes(self):
        return self.all().filter(category='size')

    def colors(self):
        return self.all().filter(category='color')

VAR_CATEGORIES = (
    ('size', 'size'),
    ('color', 'color'),
    ('package', 'package'),
    )

class Variation(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    category = models.CharField(max_length=120, choices=VAR_CATEGORIES, default='size')
    title = models.CharField(max_length=120)
    active = models.BooleanField(default=True)

    objects = VariationManager()

    def __str__(self):
        return self.title   

    def get_add_to_cart_url(self):
        return reverse("add-to-cart", kwargs={
            'slug': self.slug
        })
    def get_remove_from_cart_url(self):
        return reverse("remove-from-cart", kwargs={
            'slug': self.slug
        })

class OrderItem(models.Model):
    user = models.ForeignKey(User, 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}"

    def get_total_item_price(self):
        return self.quantity * self.item.price

    def get_total_discount_item_price(self):
        return self.quantity * self.item.discount_price

    def get_amount_saved(self):
        return self.get_total_item_price() - self.get_total_discount_item_price()

    def get_final_price(self):
        if self.item.price:#self.item.discount_price:
            return self.get_total_item_price()#self.get_total_discount_item_price()
        #return self.get_total_item_price()

VIEWS.PY:

def add_to_cart(request,slug):
    item = get_object_or_404(Item,slug=slug)
    order_item_qs = OrderItem.objects.filter(
        item=item,
        user=request.user,
        ordered=False
    )

    item_var = [] #item variation
    if request.method == 'POST':
        for items in request.POST:
            key = items
            val = request.POST[key]
            try:
                v = Variation.objects.get(
                    item=item,
                    category__iexact=key,
                    title__iexact=val
                )
                item_var.append(v)
            except:
                pass

        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 += 1
        order_item.save()

    else:
        order_item = OrderItem.objects.create(
            item=item,
            user=request.user,
            ordered=False
        )
        order_item.variation.add(*item_var)
        order_item.save()


    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.add(order_item)
            messages.info(request, "This item quantity was updated.")
            return redirect("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("order-summary")

模板(订单摘要):

{% for order_item in object.items.all %}
<div class="quantity buttons_added">
    <a href="{% url 'remove-single-item-from-cart' order_item.item.slug %}"><input type="button" value="-" class="minus"></a>
        <input type="number" value="{{ order_item.quantity }}" title="Qty" class="input-text qty text" size="4" pattern="" inputmode="">
    <a href="{% url 'add-to-cart' order_item.item.slug %}">
        <input type="button" value="+" class="plus"></a>
    </div>
 {% endfor %}

URLS.PY

from django.urls import path
from core.views import (
    HomeView,
    ItemDetailView,
    OrderSummaryView,
    CheckoutView,
    add_to_cart,
    remove_from_cart,
    remove_single_item_from_cart
)

app_name = 'core'

urlpatterns = [
    path('', HomeView.as_view(), name='homepage'),
    path('checkout/', CheckoutView.as_view(),     name='checkout'),
        path('order-summary/', OrderSummaryView.as_view(), name='order-summary'),
    path('product/<slug>/', ItemDetailView.as_view(), name='product'),
        path('add-to-cart/<slug>/', add_to_cart, name='add-to-cart'),
    path('remove-from-cart/<slug>/', remove_from_cart, name='remove-from-cart'),
    path('remove-item-cart/<slug>/', remove_single_item_from_cart, name='remove-single-item-from-cart'),

]

【问题讨论】:

  • 请同时附上您的models.py
  • 我刚刚更新了我的问题。谢谢! @Pedram

标签: python django python-2.7 python-3.7


【解决方案1】:

我认为你的模型存在一个根本问题,这使得你很难实现你想要的。

基本上,每个OrderItem 应该只属于一个变体。这样您就可以轻松跟踪每个变体的quantity

因此,从您的 OrderItem 模型中删除 Item 字段,并将 variation 字段设为外键字段。使用这种模式,添加或删除变体要简单得多;只需将变量pk 传递给add_to_cart 添加执行该过程。

这是基本的想法;您还需要进行其他小的更改,但如果有任何不清楚或存在任何进一步的问题,请告诉我。

编辑

这是您的 OrderItemVariation 模型的外观:

class Variation(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    category = models.CharField(max_length=120, choices=VAR_CATEGORIES, default='size')
    title = models.CharField(max_length=120)
    active = models.BooleanField(default=True)

    objects = VariationManager()


class OrderItem(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    ordered = models.BooleanField(default=False)
    variation = models.ForeignKey(Variation, on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)

对于你的 url,我的意思是,variation 上的 get_add_to_cart_urlget_remove_from_cart_url 方法,我认为你应该为变体的 kwarg 添加另一个 kwarg id 只需传递变体的id(没有)。

【讨论】:

  • 仍然无法正常工作,我认为变异不是导致此问题的原因。如果我添加具有变化的不同项目,则每个项目的数量都可以正常工作。但是,如果我两次添加具有不同变化的相同项目,则项目数量只会增加第一个项目。我认为这与同一项目的 slug/ID 有关。 @Pedram
  • 是的,我明白了;但是添加具有不同变体的相同项目正是您的数据库设计的边缘情况。如果您查看电子商务的数据库模式,您会发现每个变体都应单独添加到OrderItem。这是众所周知的最佳做法。
  • 另外,如果您查看当前的数据库设计,对于每个 item(产品),您将添加一个 OrderItem,因此您无法处理不同的数量变体正确,因为对于所有不同的变体,您只有 一个 quantity 字段。
  • 我认为你是对的,请你在这里重写模型代码,以便我可以清楚地理解@PEDRAM
  • 好的,我试试。谢谢@Pedram
猜你喜欢
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 2012-01-06
相关资源
最近更新 更多