# 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): """ 处理文章评论提交的视图 使用 FormView 来处理表单提交 """ form_class = CommentForm # 使用的表单类 template_name = 'blog/article_detail.html' # 表单出错时重新渲染的模板 @method_decorator(csrf_protect) def dispatch(self, *args, **kwargs): # 强制开启 CSRF 防护 return super(CommentPostView, self).dispatch(*args, **kwargs) def get(self, request, *args, **kwargs): """ GET 请求时直接跳回文章详情页(因为评论应为 POST 行为) """ 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) # 判断文章是否允许评论 (‘c’ 表示关闭评论状态) if article.comment_status == 'c' or article.status == 'c': raise ValidationError("该文章评论已关闭.") # 创建一个未保存的 comment 对象 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 # 处理父评论(即:回复某条评论) 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))