繁体   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