[英]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.