Агрегатная сумма Django по полю дочерней модели
Рассмотрите следующие модели:
from django.db import models
from django.db.models import Sum
from decimal import *
class Supply(models.Model):
"""Addition of new batches to stock"""
bottles_number = models.PositiveSmallIntegerField(
bottles_remaining = models.DecimalField(max_digits=4, decimal_places=1, default=0.0)
def remain(self, *args, **kwargs):
used = Pick.objects.filter(supply=self).aggregate(
total=Sum(Pick.n_bottles))[bottles_used__sum]
left = self.bottles_number - used
return left
def save(self, *args, **kwargs):
self.bottles_remaining = self.remain()
super(Supply, self).save(*args, **kwargs)
class Pick(models.Model):
""" Removals from specific stock batch """
supply = models.ForeignKey(Supply, on_delete = models.CASCADE)
n_bottles = models.DecimalField(max_digits=4, decimal_places=1)
Каждый раз, когда товар (в данном случае бутылки) используется, мне нужно обновить поле "bottles_remaining", чтобы показать текущее количество на складе. Я знаю, что лучшая практика обычно заключается в том, чтобы не хранить в базе данных значения, которые могут быть вычислены на лету, но мне нужно сделать это, чтобы иметь данные, доступные для использования за пределами Django.
Это часть системы управления запасами, изначально построенной на PHP через Xataface. Не будучи опытным программистом, я смог сделать большую часть этого с помощью гугла, но теперь я полностью застрял на этой ключевой функции. Функция remain(), вероятно, представляет собой полный беспорядок. Любые подсказки о том, как выполнить этот расчет и извлечь значение, будут очень признательны.
Не уверен, что вы на самом деле хотите решить и в чем именно заключается проблема.
Возможными решениями являются
- Use SQL View
CREATE VIEW bottles_extended AS
SELECT id, total_number, used, (total_number - used) as remaining
FROM bottles;
После этого вы можете просто получить данные в виде select total_number, used, remaining from bottles_extended
на стороне PHP
Add
(total_number - used) as remaining
column directly in PHP SQL queryCurrent Django solution to update field automatically on save looks not perfect but also should be working solution (in addition you may add serializers and set serializer's
remaining
field asread only
. This will prevent to change value by user manually)