[英]Django form update optimistic locking, version based
我有 django model 和视图实现如下:(+ mysql db)
class MyModel(models.Model):
name = models.CharField(max_length=100)
version = models.IntegerField(default=1, editable=False)
def updateModel(request, id):
toUpdate = MyModel.objects.get(pk=id)
if request.method=='POST':
form = MyModelForm(request.POST, instance=toUpdate)
if form.is_valid():
actual = MyModel.objects.get(pk=id)
if (actual.version == form.instance.version):
form.instance.version = form.instance.version+1
form.save()
return redirect('somewhere')
else:
#some error
form = MyModelForm(instance=toUpdate)
return render(request, 'somwhere2/createupdate.html', {'form':form})
场景是:- 当前 model 值:name="aaa", version=1,
2 个用户打开编辑表单,第一个用户将名称“aaa”更改为“bbb”并保存,第二个用户将名称“aaa”更改为“ccc”并保存。 结果是“ccc”,但我想要一些消息/版本冲突消息......问题是......没有冲突,因为即使第二个用户仍然可以看到“aaa”,而在数据库中有“bbb”已经...但是在单击 POST 按钮后,值首先更新为 bbb,并且版本已更新,因此代码无法看到,user2 在旧版本上工作...:(
我想要那种版本控制机制来防止这种情况,但我无法实现它......
如何实施?
我已经阅读了有关 django 乐观锁定等的所有内容,但无法实现,
我认为使用select_for_update()
可能会解决您的问题。 查看这篇文章。
我在想这样的事情:
def updateModel(request, id):
toUpdate = MyModel.objects.get(pk=id)
if request.method=='POST':
form = MyModelForm(request.POST, instance=toUpdate)
if form.is_valid():
with transaction.atomic():
try:
actual = MyModel.objects.filter(pk=id).select_for_update(nowait=True).get()
except OperationalError:
# raise some error
if (actual.version == form.instance.version):
form.instance.version = form.instance.version+1
form.save()
return redirect('somewhere')
else:
#some error
form = MyModelForm(instance=toUpdate)
return render(request, 'somwhere2/createupdate.html', {'form':form})
我相信我发现了一个问题。 它在这里:
in Model: version =(...) editable=False
因此,当字段不可编辑时 - 它未放置在表单中,因此您将丢失有关版本号的信息......并且无法将最初加载的版本与实际版本进行比较。
它仍然不是线程安全的,但通常会阻止 2 个用户编辑和保存表单的典型尝试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.