在 release note 中写的是
Model.save() no longer attempts to find a row when saving a new Model instance and a default value for the primary key is provided, and always performs a single INSERT query.
This makes calling Model.save() while providing a default primary key value equivalent to passing force_insert=True to model’s save(). Attempts to use a new Model instance to update an existing row will result in an IntegrityError.
In order to update an existing model for a specific primary key value, use the update_or_create() method or QuerySet.filter(pk=…).update(…) instead.
貌似是 model 中有 id 时,只会执行插入而不会更新,从而可能触发 IntegrityError。
但是我在测试的时候发现
Class Order(models.Model):
status = models.PositiveSmallIntegerField(default=1)
order = Order.objects.filter(id=1).first()
order.status = 2
order.save()
或者
order = Order()
order.id =1
order.status=2
order.save()
这里 id=1 的行已经存在,但是都能够正常保存。请问我在哪里理解错误了?又是什么情况才会触发文档中的错误。
1
vicalloy 2020-02-14 12:51:19 +08:00
你没有看清楚,“force_insert=True”的时候才会强制插入导致报错。
|
2
wuming OP @vicalloy 这上面不是说的是当提供主键时,相当于给 model.save() 传递 force_insert =True 么。也就是不需要我主动传递 force_insert
|
3
hzwjz 2020-02-14 13:32:05 +08:00 via Android
Attempts to use a new Model instance to update an existing row will result in an IntegrityError.
old_order 已存在的情况下且 id 我假设为 1,然后 new_order = Order() new_order.id = 1 new_order.save(). # IntegrityError |
4
wuming OP @hzwjz 刚才这样做了,还是没有任何错误。
old_order = Order.objects.get(id=1) print(old_order.id) #执行完之后看到的 id=1 new_order = Order() new_order.id = 1 new_order.save() #执行完之后没有任何错误。 |
5
qqxx520 2020-02-14 15:58:01 +08:00 1
我的理解, "Default value for primary key is provided"意思是在 model 建立时的主键字段有 default=xxx, 例如
Class Order(models.Model): id=models.AutoField('ID', primary_key=True, auto_created=True, default=True) status = models.PositiveSmallIntegerField(default=1) 测试代码: >>> a=Order() >>> a.save() >>> a <Order: Order object (1)> >>> a.id 1 >>> b=Order() >>> b.save() Traceback (most recent call last): ... sqlite3.IntegrityError: UNIQUE constraint failed: order_order.id >>> b.id=2 >>> b.save() >>> a,b (<Order: Order object (1)>, <Order: Order object (2)>) 但是 id 字段的 default value 是 True,似乎没什么意思,可以改进为如下的定义: import time from django.db import models def get_pk(): return int(time.time() * 10000) class Order(models.Model): id=models.AutoField('ID', primary_key=True, auto_created=True, default=get_pk) status = models.PositiveSmallIntegerField(default=1) 测试代码: >>> c=Order() >>> c.save() >>> c.id 15816669672836 >>> d=Order() >>> d.save() >>> d.id 15816669758912 -- 完毕 -- |