2014-10-02 55 views
6

我有一个Post模型的项目,那就是基本帖子。我想在每个帖子页面上创建一个链接,以便能够删除该帖子(具有适当的安全性)。通过html链接删除Django中的对象

关于堆栈溢出,有几个问题,但我似乎无法找到一个完整的,可行的答案(我使用Django 1.7),当我执行它时不会抛出错误。

我已经能够实现可以正常工作的删除功能,但需要添加一个带CSRF标记的POST表单进行验证,并且还要检查删除它的用户是否是创建它的用户。我似乎无法弄清楚如何在添加这两个

到目前为止,在我的views.py:

def delete(request, id): 
    post = Post.objects.filter(pk=id).delete() 
    return HttpResponseRedirect(reverse('posts.views.all_posts')) 

在urls.py:

url(r'^delete/(?P<id>\d+)/$','posts.views.delete'), 

在HTML:

<a href="/delete/{{ post.id }}">Delete</a> 

这一切都有效,但没有安全保障 - 因此,如何添加表单并检查指导意见。

此外,我看到一个使用DeleteView的答案,但无法让它工作。

+0

我只是想澄清,如果用户需要登录才能查看所有帖子? – catherine 2014-10-02 06:19:43

回答

8

确实,使用GET方法删除您的对象会让您容易受到CSRF attacks的影响。

DeleteView只在POST上删除,并在GET上显示确认页面。

你的代码应该是这个样子的views.py

from django.views.generic import DeleteView 

class PostDelete(DeleteView): 
    model = Post 
    success_url = reverse_lazy('posts.views.all_posts') 

urls.py

url(r'^delete/(?P<pk>\d+)/$', PostDelete.as_view(), 
     name='entry_delete'), 

您的形式(不使用确认模板有一个在文档确认模板的一个例子。 ):

<form action="{% url 'entry_delete' object.pk %}" method="post"> 
    {% csrf_token %} 
    <input type="submit" value="Delete" /> 
</form> 

如果你是t使用确认模板时,请确保将表单的action属性指向​​(this is why)。

为确保用户删除帖子是拥有它的用户,我喜欢使用mixins。假设你Post模型具有created_by外键指向User,你可以写这样一个mixin:

from django.core.exceptions import PermissionDenied 

class PermissionMixin(object): 

    def get_object(self, *args, **kwargs): 
     obj = super(PermissionMixin, self).get_object(*args, **kwargs) 
     if not obj.created_by == self.request.user: 
      raise PermissionDenied() 
     else: 
      return obj 

最后,您​​应该从这个混入继承:

class PostDelete(PermissionMixin, DeleteView): 

    model = Post 
    success_url = reverse_lazy('posts.views.all_posts') 
+0

辉煌的,完美的工作 - 我尝试没有确认屏幕,它工作得很好。我现在尝试添加确认屏幕。 – 2014-10-02 06:48:59

+0

对于任何未来的人来说,你还需要在你的urls.py中导入PostDelete,例如:from views import PostDelete – 2014-10-02 06:50:18