Если сумма всегда держится, лучше , а не , чтобы сделать поля для них. Действительно, создавая поля, это может привести к тому, что некоторые обновления могут нарушить ограничение. Да, у Django есть сигналы и т. Д., Которые могут срабатывать при сохранении модели, но некоторые вызовы ORM, такие как .update(..)
, обходят эти сигналы.
Обычно лучше аннотировать, если сумма всегда сохраняется. Это означает, что в базе данных нет явных полей, но вы указываете базе данных вычислять поля при необходимости. Таким образом, это экономит дисковое пространство для базы данных и, кроме того, делает невозможным, чтобы отношение не сохранялось.
Мы можем определить менеджер аннотаций следующим образом:
from django.db import models
class AnnotationManager(models.Manager):
def <b>__init__</b>(self, **kwargs):
super().__init__()
self.annotations = kwargs
def <b>get_queryset</b>(self):
return super().get_queryset().annotate(**self.annotations)
Затем мы можем добавить этого менеджера в модель Salary
:
from django.db import models
from django.db.models import F
class Salary(models.Model):
basic = models.IntegerField()
allowance = models.IntegerField()
incentives = models.IntegerField()
gratuity = models.IntegerField()
_gross = None
_ctc = None
<b>objects</b> = <b>AnnotationManager</b>(
gross=F('basic')+F('allowance')+F('incentives'),
ctc=F('gross')+F('gratuity')
)
Мы также можем фильтровать по следующим столбцам:
Salary.objects.filter(<b>gross__gt=100</b>)
извлечет все Salary
объекты с gross
больше 100
. Фильтрация здесь выполняется на уровне базы данных, а не на уровне Python. Django переведет вышеприведенное в запросе, который выглядит следующим образом:
SELECT salary.*,
salary.basic + salary.allowance + salary.incentives AS <b>gross</b>,
salary.basic + salary.allowance + salary.incentives + salary.gratuity AS <b>ctc</b>
FROM salary
WHERE <b>salary.basic + salary.allowance + salary.incentives > 100</b>