【问题标题】:How to handle editing conflicts in Django forms?如何处理 Django 表单中的编辑冲突?
【发布时间】:2021-03-18 08:54:12
【问题描述】:

想象以下情况:两个用户 Alice 和 Bob 正在使用 Django 表单同时编辑同一个对象。出于本示例的目的,我们使用以下模型:

class Book(models.Model):
    title = models.TextField()
    description = models.TextField()

Alice 编辑这本书以更改其标题。与此同时,Bob 编辑了这本书以更改其描述。现在,如果 Bob 是最后一个单击“保存”按钮的人,他的表单将“获胜”,并且只有书的描述会被更改。否则,如果 Alice 是最后一个保存的,则只有标题会被更改。然而,理想情况下,在保存两个表单后,数据库应该包含 Alice 的标题和 Bob 的描述。

我可以想到一些可能的解决方案来防止这种情况发生:

  1. 锁定表单。只要 Alice 请求图书编辑表单,她就会获得一个锁,在她单击“保存”后会释放该锁。当 Bob 尝试请求相同的表单时,他可能会收到 Alice 已经在编辑同一本书的错误或警告消息。这里的问题是如果当然要处理陈旧的锁。

  2. 校验和正在编辑的数据。该表单可能包含底层数据的隐藏校验和。如果在提交表单时校验和已更改,则可能会警告用户他们正在更新的对象同时已更改。它可以阻止他们保存或警告他们

  3. 在服务器端解决合并冲突。这是我更喜欢的解决方案。不知何故,服务器应该能够发现 Alice 只更改了书名,而 Bob 更改了描述。也许 ModelForm 可以根据表单的 changed_data 属性修改为使用 update_fields 调用 save()

我确信其他人已经解决了这个问题,我希望现有的 Django 应用程序可以实现上述解决方案之一。但是,我很难找到有关此主题的信息。处理 Django 表单中的编辑冲突的最佳方法是什么?

【问题讨论】:

  • 我认为像当前 SO 编辑系统这样的版本控制系统将适合这种情况

标签: django concurrency django-forms locking


【解决方案1】:

您可以在模型中添加值:

class Book(models.Model):
title = models.TextField()
description = models.TextField()
lock = models.BooleanField()
last_change = models.DateTimeField()
last_user_change = models.ForeignKey(User)

在视野中

def edit_book(request, pk):
    book = get_object_or_404(Book, pk=pk)
    user = request.user.id 
    if book.lock == 0:
        book.lock = 1
        book.save()
        if request.method == "POST":
            form = edit_bookForm(request.POST or None)
            if form.is_valid():
                f=form(commit=False)
                f.last_change = datetime.now()
                f.last_user_change = user
                f.save()
                book.lock = 0
                book.save()
             return redirect('ok')
         return render(request, 'urformhtml.html', {})
     else:
         return render(request, 'byebye.html', {})

  

或者你可以添加 last_change_title 和 last_change_description 来拆分更新......

只是一个想法

【讨论】:

  • 好主意!这完全回答了问题的第 1 点!
猜你喜欢
  • 2010-12-02
  • 2011-09-09
  • 2014-08-14
  • 2014-02-21
  • 2022-11-09
  • 2017-08-04
  • 2011-06-26
  • 2021-09-06
  • 2013-08-27
相关资源
最近更新 更多