Рассчитать сумму для разных типов данных в Джанго - PullRequest
0 голосов
/ 12 мая 2019

У меня есть столбцы в БД, называемые Цена и Кол-во Цена - это текстовое поле, потому что оно должно быть записано как $ 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>

Результат должен быть в состоянии выполнить вычисления total_price на основе OrderId и показать его шаблону.

Кто-нибудь может помочь мне решить эту проблему? Действительно ценю

1 Ответ

2 голосов
/ 12 мая 2019
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 с именем TotalPrice, но, если вы измените его на DecimalField, тогда представления будут

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

добавить в существующий заказ. Вы также можете установить это значение при создании нового заказа, так же, как вы уже это делаете. Если вы всегда сохраняете итоговую цену в базе данных, вам даже не нужны никакие из указанных выше операций запроса, но вы можете просто получить к ней прямой доступ.

...