You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DjangoBlog/comments/views.py

96 lines
4.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Create your views here.
# 导入Django相关异常、响应和工具类
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 # 用户模型
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' # 表单渲染和错误显示的模板
@method_decorator(csrf_protect)
def dispatch(self, *args, **kwargs):
"""
重写dispatch方法添加CSRF保护
使用method_decorator将csrf_protect装饰器应用到dispatch方法
确保表单提交经过CSRF验证防止跨站请求伪造攻击
"""
return super(CommentPostView, self).dispatch(*args, **kwargs)
def get(self, request, *args, **kwargs):
"""
处理GET请求
当通过GET访问评论提交URL时重定向到对应的文章详情页的评论区
"""
article_id = self.kwargs['article_id'] # 从URL参数中获取文章ID
article = get_object_or_404(Article, pk=article_id) # 获取对应的文章对象
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) # 根据用户ID获取对应的用户对象
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("该文章评论已关闭.")
# 保存表单数据但不提交到数据库commit=False以便后续补充字段
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))