|
|
# Create your views here.
|
|
|
from django.core.exceptions import ValidationError # 导入验证异常类,用于处理验证错误
|
|
|
from django.http import HttpResponseRedirect # 导入HTTP重定向类,用于页面跳转
|
|
|
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 # 从accounts应用导入用户模型
|
|
|
from blog.models import Article # 从blog应用导入文章模型
|
|
|
from .forms import CommentForm # 从当前应用导入评论表单
|
|
|
from .models import Comment # 从当前应用导入评论模型
|
|
|
|
|
|
|
|
|
class CommentPostView(FormView):
|
|
|
"""评论提交视图类,处理评论发布功能"""
|
|
|
form_class = CommentForm # 指定使用的表单类为CommentForm
|
|
|
template_name = 'blog/article_detail.html' # 指定表单验证失败时渲染的模板
|
|
|
|
|
|
@method_decorator(csrf_protect) # 为dispatch方法添加CSRF保护
|
|
|
def dispatch(self, *args, **kwargs):
|
|
|
# 调用父类的dispatch方法,处理请求分发
|
|
|
return super(CommentPostView, self).dispatch(*args, **kwargs)
|
|
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
"""处理GET请求:重定向到文章详情页的评论区"""
|
|
|
article_id = self.kwargs['article_id'] # 从URL参数中获取文章ID
|
|
|
article = get_object_or_404(Article, pk=article_id) # 获取对应的文章对象,不存在则返回404
|
|
|
url = article.get_absolute_url() # 获取文章的绝对URL
|
|
|
return HttpResponseRedirect(url + "#comments") # 重定向到文章详情页的评论区锚点
|
|
|
|
|
|
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 # 文章对象
|
|
|
})
|
|
|
|
|
|
def form_valid(self, form):
|
|
|
"""处理表单验证通过后的逻辑:保存评论并跳转"""
|
|
|
user = self.request.user # 获取当前登录用户
|
|
|
author = BlogUser.objects.get(pk=user.pk) # 获取用户对应的BlogUser对象
|
|
|
article_id = self.kwargs['article_id'] # 获取文章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)) # 拼接URL,包含评论ID锚点
|