# 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): # jrx: 评论表单类 form_class = CommentForm # jrx: 渲染的模板(文章详情页) template_name = 'blog/article_detail.html' # jrx: 启用CSRF保护 @method_decorator(csrf_protect) def dispatch(self, *args, **kwargs): return super(CommentPostView, self).dispatch(*args, **kwargs) # jrx: 处理GET请求:重定向到文章详情页的评论区 def get(self, request, *args, **kwargs): article_id = self.kwargs['article_id'] # jrx: 从URL获取文章ID article = get_object_or_404(Article, pk=article_id) # jrx: 获取文章对象,不存在则404 url = article.get_absolute_url() # jrx: 获取文章详情页URL return HttpResponseRedirect(url + "#comments") # jrx: 重定向到评论区锚点 # jrx: 表单验证失败时的处理 def form_invalid(self, form): article_id = self.kwargs['article_id'] article = get_object_or_404(Article, pk=article_id) # jrx: 重新渲染文章详情页,携带错误表单和文章数据 return self.render_to_response({ 'form': form, 'article': article }) # jrx: 表单验证通过后的处理(核心逻辑) def form_valid(self, form): """提交的数据验证合法后的逻辑""" user = self.request.user # jrx: 当前登录用户 author = BlogUser.objects.get(pk=user.pk) # jrx: 获取用户详细信息 article_id = self.kwargs['article_id'] # jrx: 文章ID article = get_object_or_404(Article, pk=article_id) # jrx: 获取文章对象 # jrx: 检查文章是否允许评论 if article.comment_status == 'c' or article.status == 'c': raise ValidationError("该文章评论已关闭.") # jrx: 不立即保存表单数据,先处理关联关系 comment = form.save(False) comment.article = article # jrx: 关联评论到文章 # jrx: 根据站点设置决定评论是否需要审核 from djangoblog.utils import get_blog_setting settings = get_blog_setting() if not settings.comment_need_review: comment.is_enable = True # jrx: 无需审核则直接启用 comment.author = author # jrx: 设置评论作者 # jrx: 处理回复功能(如果存在父评论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 # jrx: 关联到父评论 comment.save(True) # jrx: 保存评论到数据库 # jrx: 重定向到文章详情页的当前评论位置 return HttpResponseRedirect( "%s#div-comment-%d" % (article.get_absolute_url(), comment.pk))