Удаление комментариев в Django
У меня возникли проблемы с получением функции удаления пользовательских комментариев для моего django блога. Логика следующая:
- пользователь, оставивший комментарий под записью блога и вошедший в систему, увидит кнопку Delete рядом со своим комментарием
- после нажатия на кнопку удаления комментария пользователь попадает на страницу Comment_confirm_delete для подтверждения удаления .
Ниже приведено то, что у меня есть:
Models.py
from django.db import models
from django.contrib.auth.models import User
from cloudinary.models import CloudinaryField
STATUS = ((0, "Draft"), (1, "Published"))
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="blog_posts")
updated_on = models.DateTimeField(auto_now=True)
content = models.TextField()
featured_image = CloudinaryField('image', default='placeholder')
excerpt = models.TextField(blank=True)
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
likes = models.ManyToManyField(User, related_name='blog_likes', blank=True)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def number_of_likes(self):
return self.likes.count()
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
name = models.CharField(max_length=80)
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=False)
class Meta:
ordering = ['-created_on']
def __str__(self):
return f"Comment {self.body} by {self.name}"
def get_absolute_url(self):
return reverse('post-detail', kwargs={'comment': id})
urls.py
from . import views
from .views import CommentDeleteView
from django.urls import path
urlpatterns = [
path("", views.PostList.as_view(), name="home"),
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
path('like/<slug:slug>', views.PostLike.as_view(), name='post_like'),
path('delete/<comment_id>', views.CommentDeleteView.as_view(), name='comment_confirm_delete')
]
views.py
from django.shortcuts import render, get_object_or_404, reverse
from django.urls import reverse_lazy
from django.views.generic.edit import DeleteView
from django.views import generic, View
from django.http import HttpResponseRedirect
from .models import Post, Comment
from .forms import CommentForm
class PostList(generic.ListView):
model = Post
queryset = Post.objects.filter(status=1).order_by('-created_on')
template_name = 'index.html'
paginate_by = 4
class PostDetail(View):
def get(self, request, slug, *args, **kwargs):
queryset = Post.objects.filter(status=1)
post = get_object_or_404(queryset, slug=slug)
comments = post.comments.filter(approved=True).order_by("-created_on")
liked = False
if post.likes.filter(id=self.request.user.id).exists():
liked = True
return render(
request,
"post_detail.html",
{
"post": post,
"comments": comments,
"commented": False,
"liked": liked,
"comment_form": CommentForm()
},
)
def post(self, request, slug, *args, **kwargs):
queryset = Post.objects.filter(status=1)
post = get_object_or_404(queryset, slug=slug)
comments = post.comments.filter(approved=True).order_by("-created_on")
liked = False
if post.likes.filter(id=self.request.user.id).exists():
liked = True
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
comment_form.instance.email = request.user.email
comment_form.instance.name = request.user.username
comment = comment_form.save(commit=False)
comment.post = post
comment.save()
else:
comment_form = CommentForm()
return render(
request,
"post_detail.html",
{
"post": post,
"comments": comments,
"commented": True,
"liked": liked,
"comment_form": CommentForm()
},
)
class PostLike(View):
def post(self, request, slug):
post = get_object_or_404(Post, slug=slug)
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
else:
post.likes.add(request.user)
return HttpResponseRedirect(reverse('post_detail', args=[slug]))
class CommentDeleteView(DeleteView):
model = Comment
template_name = 'comment_confirm_delete.html'
success_url = "/"
def test_func(self, comment_id):
comment = self.get_object()
if self.request.user == comment.name:
return render(request, "comment_confirm_delete.html")
else:
return HttpResponseRedirect(reverse('post_detail', args=[slug]))
post_detail.html
<!-- The body of the comment goes before the | -->
{{ comment.body | linebreaks }}
{% if user.username == comment.name %}
<a href="{% url 'comment_confirm_delete' comment.id %}"i class="fas fa-trash">
Delete</a>
Я ищу совета и конкретных комментариев о том, что нужно исправить в структуре. На данный момент я получаю ошибку : Generic detail view CommentDeleteView должен быть вызван с объектом pk или slug в URLconf.
большое спасибо
Измените url-путь к удалению комментария на:
path('delete/<int:pk>', views.CommentDeleteView.as_view(), name='comment_confirm_delete')