Как рассчитать django полей модели - PullRequest
1 голос
/ 22 апреля 2020

В моих моделях есть следующие поля:

class Materiale(models.Model):
    quantity=models.DecimalField(max_digits=5, decimal_places=2, default=0)
    price=models.DecimalField( max_digits=5, decimal_places=2, default=0)
    VAT=models.DecimalField(max_digits=5, decimal_places=2, default=0)
    VAT_amount=models.DecimalField(max_digits=5, decimal_places=2, default=0)

Но VAT_amount является результатом quantity*price*VAT.

Как автоматически хранить в моей базе данных это значение ??? Важно, чтобы поле (VAT_amount) присутствовало в базе данных.

Спасибо.

1 Ответ

1 голос
/ 22 апреля 2020

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

Вы можете удалить поле VAT_amount, а затем .annotate(..) ваш набор запросов, включив в него VAT_amount, например:

from django.db.models import F

Materiale.objects.annotate(<b>VAT_amount=F('quantity')*F('price')*F('vat')</b>)

Materiale объекты, которые возникают из этого набора запросов, будут иметь дополнительный атрибут .VAT_amount, который содержит результат формулы.

Если вам это нужно часто, вы можно добавить это к диспетчеру этой модели, так что это делается автоматически при каждом доступе к Materiale.objects:

class <b>MetarialeManager</b>(models.Manager):

    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).annotate(
            <b>VAT_amount=F('quantity')*F('price')*F('vat')</b>
        )

class Materiale(models.Model):
    quantity=models.DecimalField(max_digits=5, decimal_places=2, default=0)
    price=models.DecimalField( max_digits=5, decimal_places=2, default=0)
    VAT=models.DecimalField(max_digits=5, decimal_places=2, default=0)

    <b>objects = MaterialeManager()</b>
...