Как суммировать поля модели Django - PullRequest
2 голосов
/ 18 мая 2019
class Salary() :
    Basic = models. IntegerField () 
    Allowance = models. IntegerField () 
    Incentivies = models.  IntegerField () 
    gross = models. IntegerField () 
    gratuity = models. IntegerField () 
     Ctc = models. IntegerField () 

Здесь моя проблема: брутто = базовый + пособие + стимулы

ctc = брутто + чаевые

Как мне суммировать, нет необходимости вводить значение брутто или ctc.Стоит сумма

Ответы [ 4 ]

4 голосов
/ 18 мая 2019

Лучше определить gross и ctc как методы или свойства модели.В противном случае это приведет к избыточности данных.Также лучше использовать snake_casing для имен полей.

class Salary() :
    basic = models.IntegerField() 
    allowance = models.IntegerField() 
    incentives = models.IntegerField() 
    gratuity = models.IntegerField() 

    @property
    def gross(self):
        return self.basic + self.allowance + self.incentives

    @property
    def ctc(self):
        return self.gross + self.gratuity
3 голосов
/ 18 мая 2019

Если сумма всегда держится, лучше , а не , чтобы сделать поля для них. Действительно, создавая поля, это может привести к тому, что некоторые обновления могут нарушить ограничение. Да, у 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>
1 голос
/ 18 мая 2019

ответ Ахилспа точный, вы должны вычислить их в модельных методах.

Вы также можете вычислить их в базе данных.

salaries = Salary.objects.annotate(
    gross = F('basic') + F('allowance') + F('incentives'),
    ctc = F('gross') + F('gratuity')
)

Вы можете дажесоздайте собственный менеджер так, чтобы он всегда вычислялся:

from django.db.models import Manager, Model

SalaryManager(Manager):
    def get_queryset(self):
        return super().get_queryset.annotate(
            gross = F('basic') + F('allowance') + F('incentives'),
            ctc = F('gross') + F('gratuity')
        )

class Salary(Model):
    ... # Other fields
    objects = SalaryManager()

Тогда для любого экземпляра зарплаты, который был извлечен из базы данных с помощью ORM, уже будут рассчитаны атрибуты gross и ctc.

0 голосов
/ 18 мая 2019
@receiver(pre_save, sender=OfferLetter)
def my_callback(sender, instance, *args, **kwargs):
    instance.gross_salary = instance.basic+instance.conveyance_allowance+instance.special_allowance 

этот тоже хорошо работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...