# FRR:该模块定义评论提交的视图类,负责处理用户提交评论的表单验证、 # 数据存储及页面跳转等逻辑,是评论功能与用户交互的核心处理层。 from django.core.exceptions import ValidationError # 导入验证异常类,用于处理评论关闭等错误 from django.http import HttpResponseRedirect # 导入重定向响应类,用于提交后跳转 from django.shortcuts import get_object_or_404 # 导入对象获取工具,不存在时返回404 from django.utils.decorators import method_decorator # 导入方法装饰器工具 from django.views.decorators.csrf import csrf_protect # 导入CSRF保护装饰器 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 # 导入评论模型,用于存储评论数据 # FRR:评论提交视图类,继承FormView处理表单提交逻辑 class CommentPostView(FormView): form_class = CommentForm # 指定使用的表单类为CommentForm template_name = 'blog/article_detail.html' # 表单验证失败时渲染的模板(文章详情页) # FRR:为视图方法添加CSRF保护装饰器,防止跨站请求伪造攻击 @method_decorator(csrf_protect) def dispatch(self, *args, **kwargs): # 调用父类的dispatch方法,确保视图正常处理请求 return super(CommentPostView, self).dispatch(*args, **kwargs) # FRR:处理GET请求(直接访问评论提交URL时) def get(self, request, *args, **kwargs): article_id = self.kwargs['article_id'] # 从URL中获取文章ID article = get_object_or_404(Article, pk=article_id) # 获取对应的文章,不存在则返回404 url = article.get_absolute_url() # 获取文章详情页的URL # 重定向到文章详情页的评论区(#comments为评论区锚点) return HttpResponseRedirect(url + "#comments") # FRR:表单验证失败时的处理逻辑 def form_invalid(self, form): article_id = self.kwargs['article_id'] # 获取文章ID article = get_object_or_404(Article, pk=article_id) # 获取文章对象 # 渲染文章详情页,传递错误的表单对象和文章对象(便于前端显示错误信息) return self.render_to_response({ 'form': form, 'article': article }) # FRR:表单验证成功后的处理逻辑(核心方法) def form_valid(self, form): """提交的数据验证合法后的逻辑""" user = self.request.user # 获取当前登录用户 author = BlogUser.objects.get(pk=user.pk) # 获取用户对应的BlogUser实例 article_id = self.kwargs['article_id'] # 从URL获取文章ID article = get_object_or_404(Article, pk=article_id) # 获取文章对象 # FRR:检查文章是否允许评论(状态为关闭则抛出验证异常) if article.comment_status == 'c' or article.status == 'c': raise ValidationError("该文章评论已关闭.") # FRR:创建评论对象但不保存到数据库(save(False)) comment = form.save(False) comment.article = article # 关联评论到当前文章 # FRR:根据网站设置决定评论是否需要审核(默认需要审核,is_enable=False) from djangoblog.utils import get_blog_setting settings = get_blog_setting() # 获取博客全局设置 if not settings.comment_need_review: # 若无需审核 comment.is_enable = True # 直接设为启用状态 comment.author = author # 关联评论作者为当前登录用户 # FRR:处理回复功能(若存在父评论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 # 关联到父评论 # FRR:保存评论到数据库(save(True)触发模型的save方法和信号) comment.save(True) # FRR:重定向到文章详情页的当前评论位置(锚点定位到具体评论) return HttpResponseRedirect( "%s#div-comment-%d" % (article.get_absolute_url(), comment.pk))