我在db中有名为Price and Qty的列。 Price是文本字段,因为它需要写为$ 12(例如)。而数量是整数。
但是当我运行我的代码时。它显示错误
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计算并将其显示在模板上。
任何人都可以帮助我解决这个问题吗?真的很感激
答案 0 :(得分:2)
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
中有一个字段。我看到您有一个名为TextField
的{{1}},但是假设您将其更改为TotalPrice
,则视图将是
DecimalField
添加到现有订单。您也可以像创建新订单一样设置此值。如果您总是将总价格存储在数据库中,那么您甚至不需要上面的任何查询操作,而只需直接访问它即可。