【发布时间】: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?
【问题讨论】: