首页 > 解决方案 > 使用 Model.objects.create() 时未调用 Django 模型 save() 方法

问题描述

我的模型中有一个主键 ID CharField Image,我想为新创建的对象创建唯一的 ID。我尝试通过覆盖模型的保存方法来实现这一点:

    def save(self, *args, **kwargs):
        if not self.pk: # is created
            self.id = uuid.uuid4().hex
            while Image.objects.filter(id=self.id).exists():
                self.id = uuid.uuid4().hex
        return super().save(*args,**kwargs)

问题是,save()当我用 创建对象时似乎没有被调用Image.objects.create(),它只在我用创建对象image=Image(...)然后调用时才被调用image.save()。结果,除非指定,否则新创建的对象没有分配 id,这会导致 PostgreSQL 抛出non_unique primary key错误。

如何确保在调用时创建唯一 ID Image.objects.create()

Django 版本:1.11.3

更新:我意识到也没有调用覆盖的 save() 方法。原来问题是我save在迁移中调用模型的方法。正如这篇文章中指出的那样,自定义模型方法在迁移中不可用。我必须将模型的保存方法复制到迁移文件中。

标签: djangopostgresql

解决方案


这一般是做不到的。在您的 if 语句检查 ID 尚不存在和您设置它之间,其他东西可以添加一个具有该 ID 的新行。这就是使用其他解决方案的原因——数据库确保唯一的自动递增 ID,或者唯一机会非常小的 UUID。

幸运的是,你使用了一个。使用 UUID 的习惯是假设它们是唯一的。

这样做的方法是将返回唯一 ID 的函数设置为字段的默认值:

def uuid_hex():
    return uuid.uuid4().hex

class YourModel(models.Model):
    id = CharField(unique=True, primary_key=True, default=uuid_hex, null=False)

推荐阅读