#django
#django
Вопрос:
У меня есть данные, подобные приведенным ниже. Необходимо получить итоговое значение путем вычисления price - discount%
и суммы всех. Как использовать aggregate здесь
models.py
class Order(TimeStamp):
code = models.CharField(max_length=255, null=True, blank=True)
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, null=True, blank=True, related_name='order_item')
name = models.CharField(max_length=255, null=True, blank=True)
discount = models.FloatField(null=True, blank=True)
price = models.FloatField(null=True, blank=True)
def __str__(self):
return self.name
Комментарии:
1. Пожалуйста, поделитесь соответствующей моделью (моделями).
2. @WillemVanOnsem пожалуйста, проверьте
Ответ №1:
Вы можете рассчитать сниженную цену для каждого товара через .annotate(…)
[Django-doc]:
from django.db.models import F, Sum
OrderItem.objects.annotate(
total=F('price') * 0.01 * (100-F('discount'))
)['total']
Если вы хотите суммировать цены со скидкой, мы можем использовать Sum
выражение [Django-doc]:
from django.db.models import F, Sum
OrderItem.objects.aggregate(
total_price=Sum(F('price') * 0.01 * (100-F('discount')))
)['total_price']
или для определенного порядка:
from django.db.models import F, Sum
myorder.order_item.aggregate(
total_price=Sum(F('price') * 0.01 * (100-F('discount')))
)['total_price']
Вероятно, вы захотите сделать это для Order
объекта:
from django.db.models import F, Sum
Order.objects.annotate(
total_price=Sum(F('order_item__price') * 0.01 * (100-F('order_item__discount')))
)
Order
Объекты, которые возникают в результате этого, будут иметь дополнительный атрибут .total_price
, который содержит общую цену.
Примечание: я бы воздержался от создания большого количества (всех) полей
NULL
, доступных. Это означает, что если поля естьNULL
, то также могут бытьNULL
выражения и агрегаты с этими полями, и часто так и есть, если одно из включенных полей естьNULL
. ЧастоNULL
доступные поля встречаются редко и используются, если допустимо наличие отсутствующей информации.
Примечание:
related_name=…
[Django-doc] — это имя менеджера для извлечения связанных объектов в обратном порядке. Поэтому обычноrelated_name
ForeignKey
илиManyToManyField
является множественным числом, например,order_items
вместо.order_item
Примечание: Возможно, имеет больше смысла работать с
DecimalField
[Django-doc],FloatField
чем с [Django-doc],, поскольку десятичная дробь имеет фиксированную точность и меньше ошибок округления, особенно при работе с финансовыми данными, что является более точным.
Комментарии:
1. Спасибо за ваш ответ.