我有一个Post模型项目,即基本帖子。我想在每个帖子页面上创建一个链接,以便能够删除该帖子(具有适当的安全性)。
关于堆栈溢出有一些问题,但我似乎无法找到一个完整的,可行的答案(我正在使用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的答案,但是也无法使用DeleteView。
答案 0 :(得分:9)
实际上,使用GET方法删除对象会使您容易受到CSRF attacks的攻击。</ p>
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>
如果您没有使用确认模板,请务必将表单的action
属性指向DeleteView
(this is why)。
为了确保用户删除帖子是拥有它的用户,我喜欢使用mixins。假设您的Post
模型的created_by
外键指向User
,您可以编写如下混音:
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
最后,您的DeleteView
应继承此mixin:
class PostDelete(PermissionMixin, DeleteView):
model = Post
success_url = reverse_lazy('posts.views.all_posts')