Вычисляемое поле на основе метода внутри модели Джанго

Как автоматически заполнить поле в моей модели PurchaseOrder:

class PurchasedOrder(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.IntegerField()


    @property
    def batch_cost(self):
        return self.quantity * self.product.unit_price

    def __str__(self):
        return self.product.name

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

Я попробовал следующее, но это не сработало:

def calculate_batch_cost(self):
    return self.quantity * self.product.unit_price

batch_cost = models.FloatField(default=calculate_batch_cost)

Я буду признателен за вашу помощь <3

Всего 2 ответа


Если это поле необходимо указать и изменить каждый раз, когда объект создается или обновляется, вы можете добавить его в функцию сохранения:

def save(self, *args, **kwargs):
    self.batch_cost = self.calculate_batch_cost()
    super(PurchasedOrder, self).save(*args, **kwargs)

И, конечно же, вам нужно добавить поле внутри модели

batch_cost = models.FloatField()

Тогда вы все еще можете использовать свою функцию Calculate_batch_cost в другом месте вашего кода.


Вы можете .annotate(..) [Django-doc] это в QuerySet , например:

from django.db.models import F

PurchasedOrder.objects.annotate(
    batch_cost=F('product__unit_price') * F('quantity')
).filter(
    batch_cost__gt=100  # An example of filtering
)

PurchasedOrder .batch_cost этого .batch_cost будут иметь атрибут .batch_cost который является unit_price продукта, умноженной на quantity .

Затем мы можем, например, отфильтровать по этому. Например, в приведенном выше запросе мы получим все batch_cost с значением batch_cost больше 100 .


Есть идеи?

10000