Removing objects in Django via html link

I have a project with a Post model, these are basic messages. I want to create a link on each page of the message in order to delete this entry (with appropriate security).

There are several questions about this when stack overflows, but I canโ€™t find a complete, workable answer (I use Django 1.7) that does not cause errors when implementing it.

I was able to implement a delete function that works fine, but you need to add a POST form with a CSRF token to verify, and also verify that the user deleting it is the one who created it. I canโ€™t figure out how to add these two.

So far in my views.py:

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

In urls.py:

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

In html:

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

It all works, but there is no security - so rate the manual for adding a form and validation.

In addition, I saw an answer that uses DeleteView, but could not get it to work.

+6
source share
1 answer

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

DeleteView only deletes the POST and shows the confirmation page in GET.

Your code should look something like this: 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. The documents have an example of a confirmation template):

 <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, be sure to specify the action form attribute on DeleteView ( thatโ€™s why ).

For the user to delete the message, this is the user to whom it belongs. I like to use mixins . Assuming your Post model has a created_by foreign key pointing to User , you can write mixin as:

 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') 
+8
source

Source: https://habr.com/ru/post/976132/


All Articles