考虑以下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")
从一个空的数据库开始:
在管理界面中添加一个实例:
到目前为止还不错。现在去修改该实例:
嗯?刚刚发生了什么?当应该可靠地期望Django执行UPDATE时,它才执行INSERT。
直接来自How Django knows to UPDATE vs. INSERT:
您可能已经注意到Django数据库对象使用相同的save()方法创建和更改对象。 Django提取了使用INSERT或UPDATE SQL语句的需求。具体来说,当您调用save()时,Django会遵循以下算法:
- 如果对象的主键属性设置为计算结果为True的值(即,无或空字符串以外的值),则Django将执行UPDATE。
- 如果未设置对象的主键属性,或者UPDATE未更新任何内容,则Django将执行INSERT。
现在,this question会告诉我这是因为a
是主键。首先,我没有在Django文档中看到任何提到的内容。其次,我无法从primary_key
中删除a
属性。
我更想知道为什么会这样,是什么原因导致它在Django内部发生,以及在哪里被记录(如果有的话)?是否还有其他未记录的条件可以完成INSERT?您何时会期望发生更新?
答案 0 :(得分:3)
https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.Field.primary_key
主键字段是只读的。如果更改现有对象上的主键的值然后保存,则将在旧对象的旁边创建一个新对象。