Hi,
I have orders table that has for example 2 records. each record have a product and a price so I did add an array to add them up:
def transactions(request, order):
if request.user.is_authenticated:
total=[]
order = order
item_list = OrderItem.objects.filter(order=order)
for order in item_list:
total.append(order.product.price)
ans = sum(total)
I end up having only the first price (first product), why is that since i have 2 items.
the items that has the same order id:
First, you’re possibly creating some confusion by reusing the identifier order
. To help prevent mixups, I’d recommend renaming something.
Second, you don’t need to manually iterate over the queryset. That’s what the aggregate
method is for.
You should be able to do something like:
results = OrderItem.objects.filter(order=order).aggregate(total_price=Sum('product__price')
(That’s a bit of a guess, you didn’t post your models, so I can’t be sure this is exactly the right syntax for what you need to do.)
See Aggregation | Django documentation | Django and pay particular attention to the examples for more information.
Also note, instead of adding the condition for is_authenticated
in your view, I would recommend using the appropriate decorator for your view function.
models.py:
class Product(models.Model):
name = models.CharField(max_length=500, null=True, blank=False)
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=True, null=False)
digital = models.BooleanField(default=True, null=True, blank=False)
video_name= models.CharField(max_length=500,null=True, blank=False)
price = models.FloatField(null=True, blank=False)
image = models.ImageField(upload_to='images/',null=True, blank=True)
video_file= models.CharField(max_length=700,null=True, blank=False)
video_demo= models.CharField(max_length=700,null=True, blank=False)
def __str__(self):
return self.name
@property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
date_ordered = models.DateTimeField(auto_now_add=True)
payment_date = models.DateTimeField(blank=True, null=True)
complete = models.BooleanField(default=False,null=True,blank=False)
transaction_id = models.CharField(max_length=200, null=True)
pay_confirm = models.BooleanField(default=False,null=True,blank=False)
def filename(self):
return os.path.basename(self.image.name)
def __str__(self):
return str(self.id)
@property
def shipping(self):
shipping = False
orderitems = self.orderitem_set.all()
for i in orderitems:
if i.product.digital == False:
shipping = True
return shipping
@property
def get_cart_total(self):
orderitems = self.orderitem_set.all()
total = sum([item.get_total for item in orderitems])
total = round(total, 0)
return total
@property
def get_cart_items(self):
orderitems = self.orderitem_set.all()
total = sum([item.quantity for item in orderitems])
total = round(total, 0)
return total
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, blank=True, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
quantity = models.IntegerField(default=0, null=True,blank=True)
date_added = models.DateTimeField(auto_now_add=True)
@property
def get_total(self):
total = self.product.price * self.quantity
total = round(total, 0)
return total
Did you try starting from the example provided in my previous response?
It might not be 100% correct, but it should be a starting point that you can work from.
What I’d suggest is that you experiment with this in the Django shell - it’s a lot easier to try queries like this in the shell than having to work on exposing it in a view.