# Create your views here. from django.core.exceptions import ValidationError from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404 from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect from django.views.generic.edit import FormView from accounts.models import BlogUser from blog.models import Article from .forms import CommentForm from .models import Comment # 评论提交处理视图 class CommentPostView(FormView): form_class = CommentForm# 指定使用的表单类 template_name = 'blog/article_detail.html'# 表单无效时渲染的模板 #为视图添加CSRF保护 @method_decorator(csrf_protect) def dispatch(self, *args, **kwargs): return super(CommentPostView, self).dispatch(*args, **kwargs) # 处理GET请求:直接访问评论提交URL时重定向到文章详情页评论区 def get(self, request, *args, **kwargs): article_id = self.kwargs['article_id'] article = get_object_or_404(Article, pk=article_id) url = article.get_absolute_url() return HttpResponseRedirect(url + "#comments") # 表单验证失败时的处理:重新渲染文章详情页并显示表单错误 def form_invalid(self, form): article_id = self.kwargs['article_id'] article = get_object_or_404(Article, pk=article_id) return self.render_to_response({ 'form': form, 'article': article }) # 表单验证成功后的处理:保存评论并发送通知邮件 def form_valid(self, form): """提交的数据验证合法后的逻辑""" user = self.request.user# 获取当前登录用户 author = BlogUser.objects.get(pk=user.pk)# 获取完整的用户信息 article_id = self.kwargs['article_id'] article = get_object_or_404(Article, pk=article_id) # 检查文章是否允许评论(评论状态或文章状态为关闭时抛出异常) if article.comment_status == 'c' or article.status == 'c': raise ValidationError("该文章评论已关闭.") # 创建评论实例但不保存到数据库 comment = form.save(False) comment.article = article # 获取站点配置,判断评论是否需要审核 from djangoblog.utils import get_blog_setting settings = get_blog_setting() if not settings.comment_need_review: comment.is_enable = True# 无需审核则直接启用评论 comment.author = author# 设置评论作者 # 处理父评论ID:如果存在则设置为回复评论 if form.cleaned_data['parent_comment_id']: parent_comment = Comment.objects.get( pk=form.cleaned_data['parent_comment_id']) comment.parent_comment = parent_comment # 保存评论到数据库 comment.save(True) # 重定向到文章详情页并定位到该评论锚点位置 return HttpResponseRedirect( "%s#div-comment-%d" % (article.get_absolute_url(), comment.pk))