Reputation: 63
I've spend hours today figuring out how to delete objects in Django. Now I have found and tried 4 different approaches on the Net, that only differ in whether a form/POST/GET approach is used or not. CSRF attacks are irrelevant for me, as the page is supposed to run locally.
What does the app do? So far only uploading files under a certain project name. This name is slugified and used as a key to hash files of a project together. Now I want to also delete files (later whole projects).
Here one of the approaches:
In the .html
:
<a href="{{file.pk}}/delete" class="btn btn-sm" role="button" title="Delete File">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</a>
This link is diplayed in a detail view, so the url already looks somethin like /files/SLUG/
Then in urls.py
:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^upload/$', views.file_upload, name ='upload'),
url(r'^upload/(?P<slug>[\w-]+)/$', views.file_upload, name ='upload'),
url(r'^(?P<slug>[\w-]+)/$', views.file_detail, name='detail'),
url(r'^(?P<slug>[\w-]+)/(?P<pk>\d+)/delete$', views.file_delete, name="file_delete"),
]
And finally the views.py
:
def file_delete(request, slug=None, pk=None):
instance = get_object_or_404(File, slug=slug, pk=pk)
# instance = File.objects.filter(pk=pk, slug=slug)[0] # the same as above
instance.delete() #does not work
return redirect("index") # or anything, this part is no problem
Everything runs through without any errors, but when I check the database on /admin, no file is gone. It simply does not get deleted. Sometimes, when logging in on /admin after trying a couple of times, I see multiple "File successfully deleted" messages at the login screen. But then the files are still in the database list.
Django Docs tells me delete() should return some kind of dictionary and how many objects were deleted e.g. like so:
>>> e.delete()
(1, {'weblog.Entry': 1})
But in may case it just says: None or returns a path starting with a slug.
I'd be very gratefull for any hint. I know there is at least one other post on stackoverflow concerning this, but unfortunately no answers
Upvotes: 3
Views: 7021
Reputation: 309099
The queryset delete method (e.g. File.objects.filter(...).delete()
) returns a tuple.
When you delete an instance (e.g. instance.delete()
) it returns None
.
I'm not sure what you mean by 'when I check the file list, no file is gone'. Note that when you delete a model instance, it will remove the row from the database. If the model has a FileField
, it won't automatically delete the associated file.
Upvotes: 4
Reputation: 51
I had a similar problem (that's how I found this), and I think if you simply put a '/' in the end of the URL for delete, it should work. At least thats what worked with me.
...
url(r'^(?P<slug>[\w-]+)/(?P<pk>\d+)/delete/<<<<$', views.file_delete, name="file_delete"),
]
Upvotes: 3