在 Django 中计算不同数据类型的总和
Calculate sum for different data types in Django
我在数据库中有名为价格和数量的列。价格是文本字段,因为它需要写成 $12(例如)。而 Qty 是整数。
但是当我 运行 我的代码。它显示错误
sum_count = OrderItem.objects.filter(OrderId=OrderId).aggregate(total_price=Sum('Total_Price:' 'Price[2:]' * 'Qty'))
TypeError: can't multiply sequence by non-int of type 'str'
models.py
class OrderItem(models.Model):
Table_No = models.IntegerField(blank=False)
FoodId = models.TextField()
Item = models.TextField()
Qty = models.DecimalField(max_digits=5, decimal_places=0)
Price = models.DecimalField(max_digits=10, decimal_places=2)
TotalPrice = models.TextField()
Note = models.TextField(max_length=100, null=True)
OrderId = models.TextField(max_length=100, null=True)
views.py
def cashier_view(request):
if request.method == "POST":
OrderId = request.POST.get("OrderId")
customerOrder = OrderItem(OrderId=OrderId)
cv = OrderItem.objects.filter(OrderId=OrderId)\
.annotate(total_price=Sum(F("Price") *
F("Qty"),output_field=models.DecimalField()))
grand_total = OrderItem.objects.update(TotalPrice=total_price)
return render(request, 'restaurants/cashier_page.html', {'cv': cv})
else:
return render(request, 'restaurants/cashier_view.html')
cashier_page.html
<form action="#" method="post">
{% csrf_token %}
{% for order in cv%}
<table width="800">
<tr>
<th width="800">Table Number</th>
<th width="800">Item</th>
<th width="800">Quantity</th>
<th width="800">Price</th>
<th width="800">Order Id</th>
<th width="800">Total Price</th>
</tr>
<tr>
<td width="800">{{ order.Table_No }}</td>
<td width="800">{{ order.Item }}</td>
<td width="800">{{ order.Qty }}</td>
<td width="800">{{ order.Price }}</td>
<td width="800">{{ order.OrderId }}</td>
<td width="800">{{ order.TotalPrice }}</td>
</tr>
</table>
{% endfor %}
</form>
结果应该可以根据OrderId进行total_price计算并显示给模板。
谁能帮我解决这个问题?非常感谢
aggregate(total_price=Sum('Total_Price:' 'Price[2:]' * 'Qty'))
不是真正有效的语法。为了做到以上几点,你需要像
这样的东西
from django.db.models import FloatField, Sum
from django.db.models.functions import Cast, Substr
annotate(price_str=Substr('price', 3))\
.annotate(price_int=Cast('price_str', FloatField())).\
.aggregate(total_price=Sum(F("price_int") * F("Qty"),
output_field=models.FloatField()))
但是,这不是解决问题的理想方式。您可能会发现将价格实际存储为 DecimalField
或类似的东西而不是文本更有帮助。最好对该文本进行预处理,将其转换为数字,然后将其存储在数据库中。
如果价格是一个数字,那么整个查询就是
aggregate(total_price=Sum(F("Price") * F("Qty"), output_field=models.FloatField()))
编辑
好的,在这种情况下你实际上想要 annotate
,所以试试:
from django.db import models
cv = OrderItem.objects.filter(OrderId=OrderId)\
.annotate(total_price=Sum(F("Price") * F("Qty"),
output_field=models.DecimalField()))
并且您使用 .total_price
访问它,所以:
<form action="#" method="post">
{% csrf_token %}
{% for order in cv%}
<table width="800">
<tr>
<th width="800">Table Number</th>
<th width="800">Item</th>
<th width="800">Quantity</th>
<th width="800">Price</th>
<th width="800">Order Id</th>
<th width="800">Total Price</th>
</tr>
<tr>
<td width="800">{{ order.Table_No }}</td>
<td width="800">{{ order.Item }}</td>
<td width="800">{{ order.Qty }}</td>
<td width="800">{{ order.Price }}</td>
<td width="800">{{ order.OrderId }}</td>
<td width="800">{{ order.total_price }}</td>
</tr>
</table>
{% endfor %}
</form>
要将其存储在数据库中,您需要在 OrderItem
中有一个字段。我看到您有一个名为 TotalPrice
的 TextField
,但假设您将其更改为 DecimalField
,那么视图将是
# . . .
OrderId = request.POST.get("OrderId")
customerOrder = OrderItem(OrderId=OrderId)
customerOrder.TotalPrice = customerOrder.Price * customerOrder.Qty
customerOrder.save()
添加到现有订单。您也可以在创建新订单时设置此值,就像您已经做的一样。如果你总是将总价存储在数据库中,那么你甚至不需要上面的任何查询操作,而是可以直接访问它。
我在数据库中有名为价格和数量的列。价格是文本字段,因为它需要写成 $12(例如)。而 Qty 是整数。
但是当我 运行 我的代码。它显示错误
sum_count = OrderItem.objects.filter(OrderId=OrderId).aggregate(total_price=Sum('Total_Price:' 'Price[2:]' * 'Qty'))
TypeError: can't multiply sequence by non-int of type 'str'
models.py
class OrderItem(models.Model):
Table_No = models.IntegerField(blank=False)
FoodId = models.TextField()
Item = models.TextField()
Qty = models.DecimalField(max_digits=5, decimal_places=0)
Price = models.DecimalField(max_digits=10, decimal_places=2)
TotalPrice = models.TextField()
Note = models.TextField(max_length=100, null=True)
OrderId = models.TextField(max_length=100, null=True)
views.py
def cashier_view(request):
if request.method == "POST":
OrderId = request.POST.get("OrderId")
customerOrder = OrderItem(OrderId=OrderId)
cv = OrderItem.objects.filter(OrderId=OrderId)\
.annotate(total_price=Sum(F("Price") *
F("Qty"),output_field=models.DecimalField()))
grand_total = OrderItem.objects.update(TotalPrice=total_price)
return render(request, 'restaurants/cashier_page.html', {'cv': cv})
else:
return render(request, 'restaurants/cashier_view.html')
cashier_page.html
<form action="#" method="post">
{% csrf_token %}
{% for order in cv%}
<table width="800">
<tr>
<th width="800">Table Number</th>
<th width="800">Item</th>
<th width="800">Quantity</th>
<th width="800">Price</th>
<th width="800">Order Id</th>
<th width="800">Total Price</th>
</tr>
<tr>
<td width="800">{{ order.Table_No }}</td>
<td width="800">{{ order.Item }}</td>
<td width="800">{{ order.Qty }}</td>
<td width="800">{{ order.Price }}</td>
<td width="800">{{ order.OrderId }}</td>
<td width="800">{{ order.TotalPrice }}</td>
</tr>
</table>
{% endfor %}
</form>
结果应该可以根据OrderId进行total_price计算并显示给模板。
谁能帮我解决这个问题?非常感谢
aggregate(total_price=Sum('Total_Price:' 'Price[2:]' * 'Qty'))
不是真正有效的语法。为了做到以上几点,你需要像
这样的东西from django.db.models import FloatField, Sum
from django.db.models.functions import Cast, Substr
annotate(price_str=Substr('price', 3))\
.annotate(price_int=Cast('price_str', FloatField())).\
.aggregate(total_price=Sum(F("price_int") * F("Qty"),
output_field=models.FloatField()))
但是,这不是解决问题的理想方式。您可能会发现将价格实际存储为 DecimalField
或类似的东西而不是文本更有帮助。最好对该文本进行预处理,将其转换为数字,然后将其存储在数据库中。
如果价格是一个数字,那么整个查询就是
aggregate(total_price=Sum(F("Price") * F("Qty"), output_field=models.FloatField()))
编辑
好的,在这种情况下你实际上想要 annotate
,所以试试:
from django.db import models
cv = OrderItem.objects.filter(OrderId=OrderId)\
.annotate(total_price=Sum(F("Price") * F("Qty"),
output_field=models.DecimalField()))
并且您使用 .total_price
访问它,所以:
<form action="#" method="post">
{% csrf_token %}
{% for order in cv%}
<table width="800">
<tr>
<th width="800">Table Number</th>
<th width="800">Item</th>
<th width="800">Quantity</th>
<th width="800">Price</th>
<th width="800">Order Id</th>
<th width="800">Total Price</th>
</tr>
<tr>
<td width="800">{{ order.Table_No }}</td>
<td width="800">{{ order.Item }}</td>
<td width="800">{{ order.Qty }}</td>
<td width="800">{{ order.Price }}</td>
<td width="800">{{ order.OrderId }}</td>
<td width="800">{{ order.total_price }}</td>
</tr>
</table>
{% endfor %}
</form>
要将其存储在数据库中,您需要在 OrderItem
中有一个字段。我看到您有一个名为 TotalPrice
的 TextField
,但假设您将其更改为 DecimalField
,那么视图将是
# . . .
OrderId = request.POST.get("OrderId")
customerOrder = OrderItem(OrderId=OrderId)
customerOrder.TotalPrice = customerOrder.Price * customerOrder.Qty
customerOrder.save()
添加到现有订单。您也可以在创建新订单时设置此值,就像您已经做的一样。如果你总是将总价存储在数据库中,那么你甚至不需要上面的任何查询操作,而是可以直接访问它。