【问题标题】:Django save() runs INSERT instead of UPDATE: Why?Django save() 运行 INSERT 而不是 UPDATE:为什么?
【发布时间】:2019-05-19 21:27:53
【问题描述】:

考虑以下 Django 模型:

class Outlet(models.Model):
    a = models.CharField(max_length=253, primary_key=True, db_index=True)
    def _split(self, idx):
        if not self.a:
            return None
        return self.a.split(".")[idx]
    @property
    def b(self):
        return self._split(0)
    @property
    def c(self):
        return self._split(1)

在 admin 中注册了这个类:

@admin.register(Outlet)
class OutletAdmin(admin.ModelAdmin):
    fields = ("a", "b", "c")
    readonly_fields = ("b", "c")

从一个空的数据库开始:

在管理 UI 中添加一个实例:

到目前为止还不错。现在去修改那个实例:

嗯?刚才发生了什么? Django 在应该可靠地执行 UPDATE 时才执行了 INSERT。

直接来自How Django knows to UPDATE vs. INSERT

您可能已经注意到 Django 数据库对象使用相同的 save() 方法来创建和更改对象。 Django 抽象了使用 INSERT 或 UPDATE SQL 语句的需要。具体来说,当你调用 save() 时,Django 遵循这个算法:

  • 如果对象的主键属性设置为计算结果为 True 的值(即,非 None 或空字符串的值),则 Django 执行 UPDATE。
  • 如果没有设置对象的主键属性或者 UPDATE 没有更新任何内容,Django 会执行 INSERT。

现在,this question 会告诉我这是因为 a 是主键。首先,我在 Django 文档中的任何地方都没有看到这一点。其次,我无法从a 中删除primary_key 属性。

我更想知道为什么会这样,是什么在 Django 内部导致它,以及它记录在哪里(如果有的话)? 是否存在其他未记录的条件,其中 INSERT 完成您预计何时会发生 UPDATE?

【问题讨论】:

    标签: python django


    【解决方案1】:

    https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.Field.primary_key

    主键字段是只读的。如果您更改现有对象的主键值并保存它,则会在旧对象旁边创建一个新对象。

    【讨论】:

      猜你喜欢
      • 2013-10-11
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-20
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多