【问题标题】:Django form INSERTs when I want it to UPDATE当我想要更新时,Django 表单插入
【发布时间】:2010-03-04 04:02:21
【问题描述】:

我是 Django 新手,但我在另一个站点上似乎有几乎相同的代码。我可以在 Django shell 中更新记录,但在 view.py 中,当我运行此表单时,相同的代码坚持插入新记录。

  • 我在模型中有一个“DisciplineEvent”对象。我让 Django 为主键创建“id”字段。我可以看到“id” int 列已在 MySQL 中使用 auto_increment 创建
  • 表单 DisciplineEventEntryForm 是从“DisciplineEvent”模型对象创建的。
  • 要编辑记录,填写输入表单并将 pk 放入名为“id”的隐藏字段中,该字段似乎与 POST 数据一起提交。

所以 view.py 的相关部分是这样的:

if request.method == 'POST':
    incidentId = request.POST['id']
    editedEvent = DisciplineEvent.objects.get(pk=int(incidentId))
    form = DisciplineEventEntryForm(request.POST, instance=editedEvent)
    form.save()
    variables = Context({
        'account': account,
        'date': request.POST['event_date'],
        'description': request.POST['incident_description'],
        'incident_id':incidentId,
         })
     template = get_template('disciplineform_confirm_entry.html')
     output = template.render(variables)
     response = HttpResponse(output)
     return response

我认为这会提取有问题的记录,将新的表单数据保存到其中,然后更新记录。相反,它会创建一条包含所有数据和递增主键的新记录。

【问题讨论】:

  • 能否请包含您的表单定义?
  • 也许还有模板代码。将“id”作为 POST 成员可能不是一个好主意。我现在很困惑,但你的代码有点不合常规,所以很难猜出问题可能出在哪里。
  • 如果表单有效,我只会保存表单...您确定DisciplineEvent.objects.get(pk=int(incidentId)) 返回一个对象吗?也许有些东西坏了,editedEvent 不包含任何对象。

标签: python django


【解决方案1】:

您正在尝试做的是非常规的并且可能存在安全漏洞

不应该从您在表单中填充的隐藏 id 键中获取对象的实例。用户可以轻松地更改这一点,并让您的代码覆盖他们甚至可能没有权限的其他模型实例。

标准的做法是根据url获取对象。

def view_function(request,id):
    object_to_edit = get_object_or_404(Model,id=id) #Or slug=slug
    form = ModelForm(data = request.POST or None, instance=object_to_edit)
    if form.is_valid():
        form.save()
        redirect()
    return render_to_response('template_name',{},RequestContext(request))

希望对你有帮助!

【讨论】:

  • 在什么情况下使用部分 GET 数据比使用部分 POST 数据更少安全漏洞?两者都完全开放给用户修改。
  • Kylotan:你把他和我都搞错了。 :P 他也不是通过 GET 传递参数,我也不建议他通过 POST 来传递。如果您阅读问题和答案,也许会有所帮助!
  • Kylotan:为了扩展,他已经在 POST 数据;但他使用 POSTed id alone 修改了数据库中的内容。这就是风险。
  • @becomingGuru:但是你的代码没有解决这个问题。它仍然不安全。不过你的说法是对的。
  • @becomingGuru:您已经明确表示“根据 url 获取对象”。 URL 是 GET 请求的一部分,用户可以很容易地修改表单的隐藏 POSTed 字段。重要的是如何确定“id”值并对其进行检查,而您在此答案中没有解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
相关资源
最近更新 更多