如何操纵另一个模型中一个模型字段的值?

时间:2018-06-13 20:10:38

标签: python django

我有两个型号

class Employee(models.Model):
    name = models.CharField(max_length=20)
    ID = models.IntegerField()
    basic_salary = models.IntegerField()     
    total_leave = models.IntegerField(default = 14)
    paid_leave = models.IntegerField(default = 0)
    unpaid_leave = models.IntegerField(default = 0)

def __str__(self):
    return self.name

class Leave_management(models.Model):

    name = models.OnetoOneField(Employee,on_delete= models.CASCADE)
    reason = models.CharField(max_length=50)
    from = models.DateTimeField()
    to = models.DateTimeField()
    total_days = models.IntegerField()

     def __str__(self):
        return self.name

所以,我希望减去&total; day_days' ' model-Leave_management'来自' total_leave'领域' model-Employee'。根据拍摄的叶子,我想更新' paid_leave'和' unpaid_leave'部分。

如果这两个模型是一个模型(下面的示例),我可以这样做,但我不知道如何在不同模型中执行此操作。

def save(self,*args,**kwargs):
    if self.total_days<=self.total_leave:
        self.total_leave -= self.total_days
        self.unpaid_leave = 14 - self.total_leave
   else:
       self.total_days -= 14
       self.paid_leaves = self.total_days
   super(Model_name,self).save(*args,**kwargs)

`  请指导我。

1 个答案:

答案 0 :(得分:1)

事实上,OneToOneField(..)Employee的{​​{1}} name。在数据库级别,它将存储与Employee主键对应的值,而在Django中,name将是 lazy 提取到相应的Employee。因此,我建议将您的函数重命名为(例如)employee

另一个问题是您将其定义为OneToOneField。这意味着Employee一个 Leave_management。但根据字段(reasonfromto等),Employee看起来可能只有一个,一个或多个Leave_management秒。这意味着它是ForeignKey

所以我们的模型看起来像:

class Leave_management(models.Model):

    employee = models.ForeignKey(Employee,on_delete= models.CASCADE)
    reason = models.CharField(max_length=50)
    from = models.DateTimeField()
    to = models.DateTimeField()
    total_days = models.IntegerField()

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

与已建议的__str__功能一样,我们可以通过查询self.employee获取员工的姓名,然后我们可以获取其.name属性。

但现在挑战是保存Leave_management对象时该怎么做。在这种情况下,应更新total_leavepaid_leave的数量。

我们首先要弄清total_days与[{1}}相关的Leave_management个对象中存储的Employee总数,这等于:

(Leave_management.objects.filter(employee=some_employee)
                         .aggregate(totals=Sum('total_days'))['totals'] or 0

然后,我们可以从14中减去此值,并将(可能的)剩余天数存储在paid_leave中,例如:

class Leave_management(models.Model):

    # ...

    def save(self, *args, **kwargs):
        super(Leave_management, self).save(*args, **kwargs)
        totals = (Leave_management.objects
                                  .filter(employee=some_employee)
                                  .aggregate(totals=Sum('total_days'))['totals'] or 0
        employee = self.employee
        unpaid = min(14, totals)
        employee.total_leave = 14 - unpaid
        employee.unpaid_leave = unpaid
        employee.paid_leave = totals - unpaid
        employee.save()
  

注意:通常我们通过覆盖.save(..)函数来执行 not 处理此问题,但是使用Django 信号:触发可以在保存某些对象时实现,尤其应该使用。因为可以绕过.save(..)函数更改对象,有时这些对象也可能被删除。所以上面的不是一个好的设计决策

     

即使我们使用信号,最好经常(例如每天一次)重新计算总假期,并更新相应的Employee模型。