如何重写保存方法来更改Django中的数据?

时间:2017-05-25 09:18:22

标签: django

型号:

ATTN_TYPE_CHOICES = (
    ('N', 'Entry'),
    ('X', 'Exit'),
    ('L', 'Leave'),
)


class Attn(Timestamp):
    emp_id = models.CharField(
        max_length=10
    )
    date = models.DateField()
    time = models.TimeField(
        default=time(00, 00)
    )
    type = models.CharField(
        max_length=1,
        choices=ATTN_TYPE_CHOICES,
        default='N'
    )

    @property
    def late(self):
        return type == 'N' and self.time > LATE_LIMIT

    def save(self, *args, **kwargs):
        try:
            Attn.objects.get(emp_id=self.emp_id, date=self.date, type='N')
        except Attn.DoesNotExist:
            pass
        else:
            try:
                exit = Attn.objects.get(emp_id=self.emp_id, date=self.date, type='X')
            except Attn.DoesNotExist:
                self.type = 'X'
            else:
                exit.delete()
        super(Attn, self).save(*args, **kwargs)

    class Meta:
        unique_together = ('emp_id', 'date', 'type')

我将创建三次对象。第一次很简单。类型为N。我希望save方法第二次检查类型N是否已经存在,如果存在,则将类型更改为“X”并保存第二个对象。第三次,我希望它检查N,然后检查X。但是这次它会找到X,并会在保存类型为X的新条目之前删除X的现有条目。

出于某种原因,代码似乎停留在unique_together,并且不允许我从管理面板保存数据。我应该尝试抓住Integrityerror来解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

尝试编辑这样的保存方法,

def save(self, *args, **kwargs):
    try:
        Attn.objects.get(emp_id=self.emp_id, date=self.date, type='N')
        try:
            exit = Attn.objects.get(emp_id=self.emp_id, date=self.date, type=='X')
            exit.delete()                
        except Attn.DoesNotExist:
            self.type = 'X'
        else:
            self.type = 'X'
    except Attn.DoesNotExist:
        self.type = 'N'

    return super(Attn, self).save(*args, **kwargs)

删除unique_together约束,现在不需要它,您明确覆盖了save方法并限制应用程序保存具有上述条件的对象。

修改

来自docs

  

违反约束时在模型验证期间引发的ValidationError具有unique_together错误代码。

这意味着,如果违反了unique_together约束,则在模型验证本身中引发ValidationError。如果约束失败,Django甚至都不会尝试到达save方法附近。因此,在将对象提交到数据库之前,django-admin会引发错误。