当我希望它更新时,Django形成INSERT

Sco*_*wig 0 python django

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

  • 我在模型中有一个"DisciplineEvent"对象.我让Django为主键创建"id"字段.我可以看到在MySQL中使用auto_increment创建了"id"int列
  • 形式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
Run Code Online (Sandbox Code Playgroud)

我认为这会拉出有问题的记录,将新的表单数据保存到其中,并更新记录.相反,它会创建一个包含所有数据和递增主键的新记录.

Lak*_*sad 9

你要做的是非常规和可能的安全漏洞.

不应该从表单中填充的隐藏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))
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!

  • @becomingGuru:但你的代码并没有解决这个问题.它仍然是不安全的.你说的是对的. (2认同)
  • @becomingGuru:你已经清楚地说过"根据网址获取对象".URL是GET请求的一部分,用户可以像表单的隐藏POSTed字段一样轻松修改.重要的是如何确定'id'值并对其进行检查,而你在这个答案中没有解决这个问题. (2认同)