计算Django中不同数据类型的总和

时间:2019-05-12 01:54:49

标签: django sum calculated-columns

我在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计算并将其显示在模板上。

任何人都可以帮助我解决这个问题吗?真的很感激

1 个答案:

答案 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

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