如何从 Django 中的编辑表单更新对象?

Posted

技术标签:

【中文标题】如何从 Django 中的编辑表单更新对象?【英文标题】:How to update an object from edit form in Django? 【发布时间】:2011-06-08 02:55:31 【问题描述】:

可能是一个新手问题,所以请多多包涵。

我有一个编辑模型的某个实例的 Django 表单。为了知道正在编辑哪个对象,我有一个包含对象 ID 的隐藏字段,以及包含该 ID 的 URL。

第一个问题:将对象的 id 放在隐藏字段中是正确的做法吗?

我(可能没有根据)担心仅将其作为 url 的一部分,有人可能会打开一个对象 id 的页面,将表单提交给另一个,然后该对象将被覆盖。这就是我尝试使用隐藏字段的原因。

将 id 存储在隐藏字段中的问题在于,在验证表单时,Django 抱怨该对象没有唯一的 id(很明显)。

第二个问题:如果唯一字段是表单的一部分,如何告诉 Django 忽略该键已经存在这一事实,以便更新对象?

【问题讨论】:

你可以给我看看你的表格吗? PS:是的,如果没有适当的保护措施(许可),/edit/ id / 任何人都可以访问并且很危险。 好吧,我确实有保护措施,例如检查对象是否属于已登录的用户 - 但即便如此,该用户(出于某种我不知道的原因)也可以去编辑一个意外的对象。跨度> 【参考方案1】:

你为什么不直接使用 ModelForm?

# forms.py
# ...
class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel

# views.py
# ...    
def my_view(request, id): 
    instance = get_object_or_404(MyModel, id=id)
    form = MyForm(request.POST or None, instance=instance)
    if form.is_valid():
        form.save()
        return redirect('next_view')
    return render(request, 'my_template.html', 'form': form) 

更多详情请见https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/#the-save-method。

【讨论】:

太棒了 - 这是我缺少的 instance 参数。伟大的万维网似乎确实缺乏关于在 Django 中使用表单编辑对象的教程。 这是正确的方法,但它没有回答:你的观点是如何得到这个“id”论点的? url 映射或隐藏字段是唯一的方法? 是的,而且没有任何问题。您可能可以兼顾会话,但我真的没有看到任何意义。如果将 id 传递给视图,则视图可以确定用户是否有权更新对象,并且无论视图获取对象 id 的方式如何,开发人员都应强制执行此检查。 @DominiqueGuardiola,此代码给我页面未找到(404)请求方法:GET【参考方案2】:

Django 1.6 及更高版本的更新

# forms.py
# ...
class MyForm(forms.ModelForm):

     class Meta:
     model = MyModel

# views.py  

def my_view(request, id): 
    instance = MyModel.objects.get(id=id)
    form = MyForm(request.POST or None, instance=instance)
    if form.is_valid():
          form.save()
          return redirect('next_view')
return direct_to_template(request, 'my_template.html', 'form': form)  

【讨论】:

如果视图包含文件或图片,视图描述是什么? Leonardo MyForm(request.POST or None, request.FILES or None, ...) 如何将参数从模板传递给 my_view 函数?我的意思是 % url 'my_view' % 接受的答案和这个有什么区别? 这个使用了 Model.objects.all 而不是 get_object_or_404。我会推荐这个,因为 Model.objects.all 需要较少的导入并且在其他情况下使用。

以上是关于如何从 Django 中的编辑表单更新对象?的主要内容,如果未能解决你的问题,请参考以下文章

Django 表单字段验证 - 如何判断操作是插入还是更新?

单击并在数据库中更新时在 Django 中编辑表单字段

Django-admin:如何在记录更改列表中显示指向对象信息页面的链接而不是编辑表单?

如何使用相同的 django 表单编辑/添加对象?

Django 编辑表单数据:数据被复制而不是被更新

Django - 禁用表单集中现有表单的编辑,但允许在新表单中编辑