Django 创建新记录而不是更新

Posted

技术标签:

【中文标题】Django 创建新记录而不是更新【英文标题】:Django create new record instead of updating 【发布时间】:2017-03-12 15:16:34 【问题描述】:

我有以下型号

class FooBar(models.Model):
    FOOBAR_ID = models.AutoField(primary_key=True)
    foo = models.CharField(max_length=255)
    bar = models.CharField(max_length=255)

此外,我创建了一个表单,允许我编辑 FooBar 的现有实例。我想在 foo 更改时更新现有记录,但在 bar 更改时创建一个新记录。

我认为一个好方法是重写 save 方法,因为它可以避免对数据库进行额外的查询,我通过将以下内容添加到我的 FooBar 模型中来完成.

__original_bar = None

def __init__(self, *args, **kwargs):
    super(FooBar, self).__init__(*args, **kwargs)
    self.__original_bar = self.bar

def save(self, force_insert=False, Force_update=False, *args, **kwargs):
        if self.bar != self.__original_bar:
            super(FooBar, self).save(force_insert=True, force_update=False, *args, **kwargs)
            self.__original_bar= self.bar
        else:
            super(FooBar, self).save(force_insert=False, force_update=True, *args, **kwargs)

当我更新 foo 时一切正常,但是当我更新 bar 时显示以下错误:

Key ("FOOBAR_ID")=(2) 已经存在。

我对 force_insert 的作用显然完全错误。如何强制它在保存中创建新记录?

【问题讨论】:

【参考方案1】:

您可以将主键设置为None,Django 会自动创建新记录。您可以在docs 中阅读更多相关信息。

def save(self, *args, **kwargs):
    if self.bar != self.__original_bar:
        self.FOOBAR_ID = None
        self.__original_bar= self.bar
    super(FooBar, self).save(*args, **kwargs)

【讨论】:

【参考方案2】:

您应该在使用 bar 时删除 id。在将数据发送到前端之前尝试将其删除。

发生的情况是您正尝试使用已经存在的主键“Key ("FOOBAR_ID")=(2)”向数据库添加新行。

【讨论】:

以上是关于Django 创建新记录而不是更新的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 AJAX、Django REST API 和 jQuery 以模式形式更新记录时显示外键字段名称而不是 ID

Spring Reactive Web 更新方法创建新记录而不是更新现有记录

EF 添加新记录而不是更新记录

可以将域类配置为在保存时插入新记录而不是更新吗?

Django ORM:如何根据所有记录中的列获取唯一记录(需要模型对象而不是特定值对象)

使用 Django 一次更新多条记录