Django购物车中OrderItems的总价

gc0ot86w  于 2023-05-19  发布在  Go
关注(0)|答案(3)|浏览(198)

我如何从下面的这些模型中获得购物车模型中OrderItem项目的“总”价格?我尝试在视图中做一些事情,但我得到QuerySet object has no attribute 'total'的属性错误

# views.py

def cart(request):
    cart = Cart.objects.filter(order_user=request.user)
    order_items = OrderItem.objects.filter(cart__in=cart)
    total = 0
    for i in order_items:
        total = i.quantity * i.item.price + cart.total
        cart.update(total=total)

# models.py

class OrderItem(models.Model):
    cart = models.ForeignKey('Cart', on_delete=CASCADE, null=True)
    item = models.ForeignKey(Item, on_delete=CASCADE, null=True)
    quantity = models.IntegerField(default=1)

class Item(Visits, models.Model):
    title = models.CharField(max_length=150)
    price =  models.IntegerField(default=1000)
    image = models.ImageField(upload_to='pictures', default='static/images/man.png')
    description = models.TextField(default="Item")
    visits = models.IntegerField(default=0)


class Cart(models.Model):
    order_user = models.OneToOneField(User, on_delete=CASCADE)
    ordered = models.BooleanField(default=False)
    total = models.IntegerField(default=0, help_text="100 = 1EUR")
    order_items = models.ManyToManyField(Item, related_name='carts', through=OrderItem )
s1ag04yj

s1ag04yj1#

您可以通过**.annotate(…)**[Django-doc]获取总数,从而在数据库端计算:

from django.db.models import F, Sum

def cart(request):
    cart = Cart.objects.annotate(
        price=Sum(F('orderitem__item__price') * F('orderitem__quantity'))
    ).get(
        order_user=request.user
    )
    cart.total = cart.price
    cart.save()
    # …

由此产生的cart对象将有一个额外的属性.price,它包含物品的价格乘以相应的数量。
但这也说明了为什么你不应该在Cart中保留total字段:你可以在必要的时候计算。

rt4zxlrg

rt4zxlrg2#

问题来自for循环中的第一行,在那里你写了:

total = i.quantity * i.item.price + cart.total

在这里,购物车是一个QuerySet,因为当您在cart方法的第一行中从 Cart 模型中检索cart对象时使用了filterfilter返回QuerySet,而不是object。您可以使用get来获取cart对象,因为在 CartUser 模型之间存在OneToOne关系。在你的cart方法的第一行试试:

cart = Cart.objects.get(order_user=request.user)

当你想更新一个对象时,你还需要使用save方法而不是updateupdate方法只属于QuerySet。

h22fl7wq

h22fl7wq3#

class OrderItem(DateTimeModel):
    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="order_items")
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField(default=1, blank=True, null=True)
    price = models.DecimalField(max_length=100, default=0, max_digits=7, decimal_places=2)
    total = models.DecimalField(max_digits=7, decimal_places=2, default=0)
# need to add tax percentage along with it tax may be changed in future so we need to add tax percentage in this

def __str__(self):
    return f"{self.id} - {self.order}"

def get_total(self):
    return round(float(self.price) * float(self.quantity))

def save(self, *args, **kwargs):
    self.total = self.get_total()
    super().save(*args, **kwargs)

相关问题