通过html链接删除Django中的对象 [英] Delete objects in Django via html link
问题描述
我有一个带有Post模型的项目,这是基本的帖子。我想在每个帖子页面上创建一个链接,以便能够删除该帖子(具有适当的安全性)。
I have a project with a Post model, that is basic posts. I want to create a link on each post page to be able to delete that post (with appropriate security).
关于堆栈溢出有一些问题,但是我似乎找不到一个完整,可行的答案(我正在使用Django 1.7),在实现它时不会引发错误。
There are a few questions on this on stack overflow, but I can't seem to find a complete, workable answer (I am using Django 1.7) that doesn't throw up errors when I implement it.
我已经能够实现可以正常运行的删除功能,但是需要添加带有CSRF令牌的POST表单以进行验证,还需要检查删除它的用户是否是创建它的用户。我似乎无法弄清楚如何添加这两个。
I have been able to implement a delete function which works ok, but need to add a POST form with CSRF token for validation, and also check that the user deleting it is the one that created it. I can't seem figure out how to add these two in.
到目前为止,在我看来。
So far, in my 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>
这一切都可以,但是没有安全性-请欣赏如何添加表格和检查的指南
This all works, but there is no security - so appreciate guidance on how to add a form and checking.
此外,我看到了一个使用DeleteView的答案,但也无法使之正常工作。
Also, I've seen an answer that uses DeleteView, but couldn't get that one to work either.
推荐答案
实际上,使用GET方法删除对象使您容易受到 CSRF攻击。
Indeed, using a GET method to delete your objects makes you vulnerable to CSRF attacks.
DeleteView
仅在POST上删除,并显示
DeleteView
only deletes on POST, and shows a confirmation page on 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'),
您的表单(不使用确认模板。文档中有一个确认模板的示例):
Your form (without using a confirmation template. There is an example of confirmation template in the docs):
<form action="{% url 'entry_delete' object.pk %}" method="post">
{% csrf_token %}
<input type="submit" value="Delete" />
</form>
如果您没有使用确认模板,请确保指向表单的 action
属性添加到 DeleteView
(这就是为什么)。
If you are not using a confirmation template, make sure to point the form's action
attribute to the DeleteView
(this is why).
为确保删除帖子的用户是拥有该帖子的用户,我喜欢使用 mixins 。假设您的 Post
模型具有 created_by
外键指向 User
,您可以编写如下的mixin:
To ensure the user deleting the post is the user that owns it, I like to use mixins. Assuming your Post
model has a created_by
foreign key pointing to User
, you could write a mixin like:
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继承:
Finally, your DeleteView
should inherit from this mixin:
class PostDelete(PermissionMixin, DeleteView):
model = Post
success_url = reverse_lazy('posts.views.all_posts')
这篇关于通过html链接删除Django中的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!