簡體   English   中英

Django 表單更新樂觀鎖定,基於版本

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM