覆盖models.Model中每个类的save方法

时间:2016-06-23 09:57:13

标签: django django-models

我需要获得每个继承models.Model的类,以创建和更新字段。我可以通过向每个字段添加自定义保存方法来实现此目的,

def save(self, *args, **kwargs):
    if not self.id:
        self.created = timezone.now()
    self.modified = timezone.now()
    return super(`models.Model`, self).save(*args, **kwargs)

但这违反了Don< RepeatYourself规则。

我试图覆盖models.Model:

class LogModel(models.Model):
    created = models.DateTimeField(editable=False)
    updated = models.DateTimeField()

    def save(self, *args, **kwargs):
        if not self.id:
            self.created = timezone.now()
        self.updated = timezone.now()
        return super(LogModel, self).save(*args, **kwargs)

并使用LogModel而不是models.Model,但这失败了,错误为E006( 该字段' x'与该领域的冲突' x'来自model' y.logmodel'。

修改

我的主要问题是如何在models.py

中为所有模型添加自定义特定字段

3 个答案:

答案 0 :(得分:5)

您的基本模型必须是抽象的:

class LogModel(models.Model):

    class Meta:
        abstract = True

    created = models.DateTimeField(editable=False)
    updated = models.DateTimeField()

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        # Use self._state.adding to check if this is a new instance,
        # ID not being empty is not a guarantee that the instance
        # exists in the database
        # and if `update_fields` is passed, you must add the fields to the
        # list or they won't be saved in the database.
        if force_insert or self._state.adding:
            self.created = timezone.now()
            if update_fields and 'created' not in update_fields:
                update_fields.append('created')
        self.updated = timezone.now()
        if update_fields and 'updated' not in update_fields:
            update_fields.append('updated')
        return super(LogModel, self).save(*args, **kwargs)

但是,如果您覆盖save()方法,则意味着它无法以任何形式进行编辑。如果这是您想要的,那么最好使用auto_nowauto_now_add

class LogModel(models.Model):

    class Meta:
        abstract = True

    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

答案 1 :(得分:1)

您可以在“模型”字段中定义 auto_now_add auto_now 参数,而不是覆盖保存方法,如:

created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)

有关这些参数的详细信息,请查看django docs

答案 2 :(得分:1)

可以通过定义Abstract Base Model并在那里定义save方法并通过继承抽象类来创建所有模型来完成。 e.g。

SET @id = 0;
UPDATE tbl_config SET id = @id := @id + 1 ORDER BY id;
SET @alt = CONCAT('ALTER TABLE tbl_config AUTO_INCREMENT = ', @id + 1);
PREPARE aifix FROM @alt;
EXECUTE aifix;
DEALLOCATE PREPARE aifix;

并从中创建子模型类:

class MyAbstractModel(models.Model):
    created = models.DateTimeField(editable=False)
    updated = models.DateTimeField()

    def save(self, *args, **kwargs):
        if self._state.adding:
            self.created = timezone.now()
        self.updated = timezone.now()
        return super(LogModel, self).save(*args, **kwargs)

    class Meta:
        abstract = True