2010-03-04 15 views
0

我是新來的Django,但我似乎有幾乎相同的代碼在另一個網站上工作。我可以更新Django shell中的記錄,但是在view.py中,當我運行此表單時,相同的代碼堅持插入新記錄。Django形式插入當我想要更新

  • 我在模型中有一個「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 

我認爲這將拉動記錄有問題,新形式的數據保存到它,並更新記錄。相反,它會創建一個包含所有數據和遞增主鍵的新記錄。

+0

你可以包括你的表單定義嗎? – Wogan 2010-03-04 05:02:08

+0

,也可能是模板代碼。將'id'作爲POST成員可能不是一個好主意。我現在很難過,但是你的代碼有點不合常規,所以很難猜測問題出在哪裏。 – 2010-03-04 05:53:11

+0

我只會保存表單,如果它是有效的......你確定'DisciplineEvent.objects.get(pk = int(incidentId))'返回一個對象嗎?也許有什麼東西壞了,'editEvent'不包含任何對象。 – 2010-03-04 07:15:28

回答

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)) 

希望它有幫助!

+0

以什麼方式使用部分GET數據而不是使用部分POST數據的安全漏洞?兩者完全開放供用戶修改。 – Kylotan 2010-03-04 14:15:40

+0

Kylotan:你有他和我,錯了。 :P他也沒有通過GET傳遞參數,也不是建議他通過POST來完成。 如果你**閱讀**問題和答案,它可能會有所幫助! – 2010-03-04 15:38:44

+0

Kylotan:爲了擴大,他已經在發佈數據;但他使用單獨發佈的'id' ** **修改了數據庫中的內容。這是風險。 – 2010-03-04 15:41:36