2010-06-26 134 views
18

在一個迷你博客應用程序中,我想創建一個刪除函數,以便博客的所有者可以刪除他的條目(僅限他的條目)。 我想做的唯一方法就是使用表單。 雖然我的刪除代碼似乎清晰和正確,但它不起作用。 我的代碼:在Django中刪除對象

def delete_new(request,id): 
    u = New.objects.get(pk=id).delete() 
    if request.method == 'POST': 
     form = DeleteNewForm(request.POST)  
     form.u.delete()    
     form.save() 
    return render_to_response('news/deleteNew.html', { 
      'form': form, 
      }, 
     context_instance=RequestContext(request)) 

,並在模板:

<a href='/news/delete_new/{{object.id}}/'> Delete</a> <br /> 

這是一個正確的做法?我的意思是,爲此創建一個表單? 也是,只有將刪除鏈接關聯的博客文章的ID作爲參數。這樣對嗎?我的意思是,也許任何用戶可以在url中輸入另一個ID,並刪除另一個條目(最終不是他的)

回答

16

通常,對於刪除對象,您應該使用POST(或DELETE)HTTP methods

如果你真的想使用HTTP GET爲你的例子,這裏是你需要解決什麼:

如果URL指向像你這樣的一些網址:<a href='/news/delete_new/{{object.id}}/'> Delete</a>那麼你可以簡單地寫視圖,將檢查對象屬於在用戶登錄,如果是刪除該條目,就像在代碼中你已經寫好:

def delete_new(request,id): 
    #+some code to check if New belongs to logged in user 
    u = New.objects.get(pk=id).delete() 

要檢查是否新對象belogs你需要UserNew(之間創建realation像created_by = models.ForeignKey(User)在一些用戶New模型)。

可以得到登錄的用戶是這樣的:request.user

我希望我正確地得到了你點我的回答可以幫助你以某種方式。

PS:您也可以考慮使用{% url %}標籤,而不是直接在您的模板中編寫url。

+0

它卷順利,在短短一行: U = New.objects。過濾器(created_by = request.user).get(pk = id).delete() 謝謝! :) – dana 2010-06-26 17:59:12

+0

確切地說,如果給定的用戶沒有這樣的New對象並且顯示好的錯誤消息(使用你的一個班輪,它將以500錯誤響亮地失敗),你可以添加一些錯誤處理。但基本上,這就是你需要在這裏做的一切:)我很高興我的回答對你有幫助。 – dzida 2010-06-26 18:34:15

+20

我強烈建議使用表格並檢查POST,因爲GETs到頁面不應該改變服務器上的狀態。 (雖然在實踐中這裏發生的事情是相對'安全的') – 2010-06-27 11:53:48

23

您需要使用表格,否則您很容易受到CSRF attacks的影響。在檢查請求是GET還是POST之前,您還要刪除模型。

創建一個簡單的ModelForm

from django import forms 

from .models import New 

class DeleteNewForm(forms.ModelForm): 
    class Meta: 
     model = New 
     fields = [] 

在你views.py在同一個Django應用程序:

from django.shortcuts import render, get_object_or_404 

from .forms import DeleteNewForm 
from .models import New 

def delete_new(request, new_id): 
    new_to_delete = get_object_or_404(New, id=new_id) 
    #+some code to check if this object belongs to the logged in user 

    if request.method == 'POST': 
     form = DeleteNewForm(request.POST, instance=new_to_delete) 

     if form.is_valid(): # checks CSRF 
      new_to_delete.delete() 
      return HttpResponseRedirect("/") # wherever to go after deleting 

    else: 
     form = DeleteNewForm(instance=new_to_delete) 

    template_vars = {'form': form} 
    return render(request, 'news/deleteNew.html', template_vars) 
+6

解釋爲什麼這是最好的:在任何情況下,提交,更新和刪除都必須使用POST(或PUT)請求。 GET請求可以用其他無害的鏈接掩蓋。假設一個主要的網站在example.com/account/delete/上有一個簡單的「刪除我所有的東西」,我可以在博客文章或類似TinyURL的服務中隱藏這樣的鏈接。參觀後,您會看到一個不錯的「您的個人資料已被刪除。」頁。 混合方法,如Wilfred Hughes',在GET上顯示確認頁面,其中包含帶有CSRF標記的表單。 POST請求驗證CSRF,然後最終刪除請求的資源。 – sleblanc 2013-04-01 04:02:43