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.
tentest/doc/DjangoBlog/comments/views.py

82 lines
4.5 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.

# 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))