I have a template which displays the files that a user has uploaded. I managed to make a view that allows me do delete all the files the user has uploaded, but I also would like to make it possible to delete each one individually.
I have a bootstrap card, and in the body I display each file with the delete link on the right:
<div class="card-body text-light">
{% for doc in docs %}
<ul>
<a href="/media/{{doc}}" download style="color:lightblue"><font face="Ubuntu">{{doc.document|filename}}</font></a>
<a href="#"><font face="Ubuntu" color="red">Delete</font></a>
</ul>
{%endfor%}
</div>
And in the card footer I use the view that deletes all files:
<div class="card-footer bg-transparent border-light">
<a href="{% url 'main:delete' %}"><i class="fas fa-trash-alt" style="color:red"></i> <font face="Ubuntu" color="red"><b>Delete All Files</b></font></a>
</div>
My delete view is as follows:
def delete(request, **kwargs):
documents = Document.objects.filter(owner=request.user.id)
documents.delete()
cleanup_post_delete.connect(delete, request)
return redirect('main:user_panel')
The problem is, I can't figure how to delete each file individually, thought of using the objects.get() method but it really can't help me. I would need some view that targets that specific file and deletes it.
UPDATE:
So, here is how I managed the problem:
I made another view called delete_single:
def delete_single(request, id):
document = Document.objects.get(pk=id)
document.delete(id)
return redirect('main:user_panel')
But that wasn't enough, so by searching a bit I found a way around, these two classes will help in terms of security, since I found out that otherwise my file objects may be susceptible to CSRF attacks (not that would matter right now for me, since this is just a project of mine and I don't plan anything special with it, but I take it as good practice anyways):
class PermissionMixin(object):
def get_object(self, *args, **kwargs):
obj = super(PermissionMixin, self).get_object(*args, **kwargs)
if not obj.owner == self.request.user:
raise PermissionDenied()
else:
return obj
class PostDelete(PermissionMixin, DeleteView):
model = Document
success_url = reverse_lazy('main:user_panel')
Also in urls.py:
url(r'^delete_single/(?P<pk>\d+)/$', views.PostDelete.as_view(), name='delete_single')
And finally in my template:
<form action="{% url 'main:delete_single' doc.pk %}" method="post">
{% csrf_token %}
<input class="btn btn-danger" type="submit" value="Delete" />
</form>