Reputation: 82
I have added a function that if the post is deleted by the user, it will be deleted if there is an uploaded photo, but the function does not work.
my view:
class NewsDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = News
template_name = 'news/news_delete.html'
success_url = reverse_lazy('news_list')
def delete_header_image(self, pk):
news = get_object_or_404(News, id = pk)
header_image = news.header_image
if header_image is not None:
os.remove(str(header_image))
return HttpResponseRedirect(reverse('news_list'))
else:
return HttpResponseRedirect(reverse('news_list'))
def test_func(self):
obj = self.get_object()
if self.request.user.has_perm('news.all') or self.request.user.has_perm('news.delete_news') or obj.author == self.request.user:
return True
urls:
urlpatterns = [
path('<int:pk>/delete', NewsDeleteView.as_view(), name='news_delete'),
]
models:
def get_header_image_filepath(self, filepath):
return f'images/news/header/{self.author.id}/{self.header_image}'
class News(models.Model):
title = models.CharField(max_length=255)
header_image = models.ImageField(null=True, blank=True, upload_to=get_header_image_filepath)
body = RichTextUploadingField()
datetime = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("news_detail", args=[str(self.id)])
Upvotes: 1
Views: 251
Reputation: 21822
Class based views do not work magically. They have some methods already written which are called to perform actions. Hence you writing a method delete_header_image
does not mean it will be called automatically. Instead you should override some suitable method of the class which will be called internally. For DeleteView
the method that performs the deletion is delete
and hence you should override that. Also the condition if header_image is not None
will not work since even if there is no file it will not be represented by None
instead you should simply write if header_image
for checking. Furthermore instead of deleting manually simply call ieldFile.delete
[Django Docs]:
class NewsDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = News
template_name = 'news/news_delete.html'
success_url = reverse_lazy('news_list')
def delete(self, request, *args, **kwargs):
object = self.get_object()
if object.header_image:
object.header_image.delete(save=False)
return super().delete(request, *args, **kwargs)
def test_func(self):
obj = self.get_object()
if self.request.user.has_perm('news.all') or self.request.user.has_perm('news.delete_news') or obj.author == self.request.user:
return True
Upvotes: 1