问题
for book in Book.objects.all():
Book.objects.filter(xxx).update(xxx)
book.author = 'xxx'
book.save()
分析
在类似以上的代码中,可能存在book在update时更新一次,然后又在save时更新一次,然后在save时保存的是旧的属性值,导致结果是似乎update方法没有起作用
解决方法
- 换一种算法,不要出现类似的情况
- 在save时选择更新的字段,
book.save(update_fileds=['author'])
,这样就不会替换已经更新的f属性(这要求update和save影响的字段是不同的,理应如此)
问题
for book in Book.objects.all():
do something with book
some_other_update(book)
book.save(update_fileds=[xxxx])
分析
- 如果在some_other_update中修改了除book外的其它行,更具体地,修改了遍历顺序中book之后的其它行,那么在遍历到该被修改的行时,传入some_other_update的并不是最新的值,而是Book.objects.all()读取出的旧值
- 这个问题与第一个问题的区别在于,some_other_update中update操作依赖于更新后的book,而第一个问题不存在此依赖
解决方法
给some_other_update传入book.id而不是book本身,然后在some_other_update中使用Book.objects.get(book_id)获得更新后的book
总结
- 以上两个问题表现出来的现象很相似,都是某些行没有被更新,仍为旧值
- 分析此类问题的时候,一个方向是查看是否存在后面的更新操作中用旧值替换了先前更新操作的新值,导致没有更新,另一个方向是查看是否在后面的更新操作中把先前更新前读取的旧值当作了先前更新后的新值
- 使用
for book in Book.objects.all()
这样的方式进行更新操作似乎比较容易产生代码逻辑上的问题,需要注意