在 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 中有一个字段。我看到您有一个名为 TotalPriceTextField,但假设您将其更改为 DecimalField,那么视图将是

# . . .
OrderId = request.POST.get("OrderId")
customerOrder = OrderItem(OrderId=OrderId)
customerOrder.TotalPrice = customerOrder.Price * customerOrder.Qty
customerOrder.save()

添加到现有订单。您也可以在创建新订单时设置此值,就像您已经做的一样。如果你总是将总价存储在数据库中,那么你甚至不需要上面的任何查询操作,而是可以直接访问它。