【问题标题】:Django model won't update using .update()Django 模型不会使用 .update() 更新
【发布时间】:2019-12-22 22:49:44
【问题描述】:

我正在尝试使用我的网站前端使用 Model.objects.update(**kwargs) 提供的信息更新我的数据库中的记录,但是在运行代码时我收到以下错误:

“具有此 ID 的‘记录’已经存在。”

我原以为使用“update”方法而不是“create”方法意味着已经有一条具有相同 ID 的记录并不重要/应该预期。

def find_patient(request):
    my_form = ExampleForm()
    if request.method == "POST":
        my_form = ExampleForm(request.POST)
        if my_form.is_valid():
            UserInfo.objects.update(**my_form.cleaned_data)
        else:
            print(my_form.errors)
    context = {
        'form': my_form,
        'data_input': DataInput.objects,
        'sections': SECTION_CHOICES
    }
    return render(request, 'example.html', context)

生成的错误如下所示:

  • 身份证
  • 具有此 ID 的用户信息已存在。

  • 我是否误解了“更新”的用例,如果是,我将如何使用 kwargs 更新我的数据库中给定记录的所有字段?

    【问题讨论】:

    • 您的update 旨在更新所有条记录,而不仅仅是一条记录。由于它包含主键,因此您的目标是将所有 ids 设置为特定值,这当然会引发错误。
    • 你做错了,请查看*.com/questions/4673985/…

    标签: python django


    【解决方案1】:

    您的UserInfo.objects.update(**my_form.cleaned_data) 旨在更新数据库中的所有记录。由于您的表单包含一个主键 (id),因此它将旨在将所有记录的 id 更新为给定值。然而,由于这些值应该是唯一的,这意味着它当然会引发错误。

    您可以通过在更新前进行过滤来防止这种情况发生,例如:

    UserInfo.objects.filter(
        pk=my_form.cleaned_data['id']
    ).update(**my_form.cleaned_data)

    但更新特定记录的方式通常不同:您通常在 URL 中传递主键。所以urls.py 看起来像:

    # app/urls.py
    
    from django.urls import path
    from app.views import find_patient
    
    urlpatterns = [
        # ...
        path('updatepatient/<int:pk>/', views.find_patient),
        # ...
    ]

    然后在视图中,我们可以将要更新的项目传递给表单:

    # app/views.py
    
    from django.shortcuts import get_object_or_404, redirect
    
    def find_patient(request, pk):
        instance = get_object_or_404(UserInfo, pk=pk)
        if request.method == "POST":
            my_form = ExampleForm(request.POST, instance=instance)
            if my_form.is_valid():
                my_form.save()
                return redirect('some-view-name')
        else:
            my_form = ExampleForm()
        context = {
            'form': my_form,
            'data_input': DataInput.objects.all(),
            'sections': SECTION_CHOICES
        }
        return render(request, 'example.html', context)

    如果 POST 请求成功,通常会重定向到一个页面。这是众所周知的Post/Redirect/Get pattern [wiki]

    【讨论】: