Delete objects in Django via html link

后端 未结 1 966
说谎
说谎 2021-02-06 09:37

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

There are

相关标签:
1条回答
  • 2021-02-06 10:07

    Indeed, using a GET method to delete your objects makes you vulnerable to CSRF attacks.

    DeleteView only deletes on POST, and shows a confirmation page on GET.

    Your code should look something like this in views.py:

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

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

    If you are not using a confirmation template, make sure to point the form's action attribute to the DeleteView (this is why).

    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
    

    Finally, your DeleteView should inherit from this mixin:

    class PostDelete(PermissionMixin, DeleteView):
    
        model = Post
        success_url = reverse_lazy('posts.views.all_posts')
    
    0 讨论(0)
提交回复
热议问题