Использование агрегата в свойстве модели Django
Описание схемы
![enter image description here]()
Проект может иметь несколько элементов проекта, а элемент проекта может иметь несколько затрат на приобретение. Например, капитальный проект № 1 содержит два элемента проекта:
- Кол-во. 1 приобретенное оборудование
- Одна стоимость приобретения в размере 5000 долларов США за приобретение оборудования у поставщика.
- Кол-во. 1 испытательная арматура, построенная персоналом
- Двенадцать 1000 покупок за каждую общую стоимость приобретения в размере 12 000 долларов.
Производственное оборудование может иметь только одну стоимость, связанную с его покупкой. Однако тестовое устройство может иметь несколько затрат, связанных с его конструкцией.
Желание
Я хочу иметь возможность определить общие затраты на приобретение для каждого элемента, и я хочу иметь возможность определить общие затраты на приобретение для каждого проекта. На основании приведенного выше примера:
- Общая стоимость приобретения 1-го уровня = 5000 долларов США
- Общая стоимость приобретения 2-го уровня = $12 000
- Общая стоимость приобретения капитального проекта = $17 000.
Вопросы
- Если
total_acquisition_costs
рассчитывается с использованием агрегатов Django или сохраняется как DecimalField
на моделях Project
и ProjectItem
?
-
Должен ли я создать свойство total_acquisition_costs
для моделей ProjectItem
и Project
? Мне кажется, что да, чтобы создать свойство.
Мне нравится вычислять значения с помощью агрегатов, чтобы избежать денормализации базы данных. В частности, я склоняюсь к использованию функции агрегирования Django Sum
для создания свойства total_acquisition_costs
. Тем не менее, я не собираюсь вкладывать агрегат в модель в качестве свойства, чтобы он просто возвращал значение вместо словаря.
Текущий код
Примечание. Мой текущий код не использует возможности агрегации Django, но он работает.
class ProjectItem(models.Model):
project = models.ForeignKey(CapExProject)
name = models.CharField(max_length=128)
@property
def total_acquisition_costs(self):
acquisition_costs = self.acquisitioncost_set.only(
'amount')
total_acquisition_costs = 0
for acquisition_cost in acquisition_costs:
total_acquisition_costs += acquisition_cost.amount
return total_acquisition_costs
Ответы
Ответ 1
Мне нравится ваша идея использовать Sum, но это свойство. Что-то вроде этого должно работать:
class Project(models.Model):
@property
def total_acquisition_costs(self):
return AcquisitionCost.objects.filter(item__project=self).aggregate(total=Sum("amount"))["total"]
class ProjectItem(models.Model):
@property
def total_acquisition_costs(self):
return self.acquisitioncost_set.aggregate(total=Sum("amount"))["total"]